From d52d0f6d96c27e89d80d69069dad2990fc0d732e Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 25 Nov 2014 18:36:34 -0700 Subject: [PATCH 01/70] add process=interpret support for Linux/ARM64 This makes all the tests pass for the platform=linux arch=arm64 process=interpret build. Next step: process=compile support. --- include/avian/tools/object-writer/tools.h | 1 + makefile | 96 +++++++++------ src/arm.S | 140 +++++++++++++++++++++- src/avian/arch.h | 2 +- src/avian/arm.h | 31 ++++- src/avian/common.h | 4 +- src/avian/environment.h | 1 + src/codegen/target/arm/registers.h | 7 ++ src/codegen/targets.cpp | 3 +- src/tools/object-writer/elf.cpp | 4 + src/tools/object-writer/tools.cpp | 2 + 11 files changed, 239 insertions(+), 52 deletions(-) diff --git a/include/avian/tools/object-writer/tools.h b/include/avian/tools/object-writer/tools.h index ea7651de5c..d6fb2c1a96 100644 --- a/include/avian/tools/object-writer/tools.h +++ b/include/avian/tools/object-writer/tools.h @@ -118,6 +118,7 @@ class PlatformInfo { x86 = AVIAN_ARCH_X86, x86_64 = AVIAN_ARCH_X86_64, Arm = AVIAN_ARCH_ARM, + Arm64 = AVIAN_ARCH_ARM64, UnknownArch = AVIAN_ARCH_UNKNOWN }; diff --git a/makefile b/makefile index 39056e5b3e..11f1aa74c4 100755 --- a/makefile +++ b/makefile @@ -7,12 +7,13 @@ build-arch := $(shell uname -m \ | sed 's/^i.86$$/i386/' \ | sed 's/^x86pc$$/i386/' \ | sed 's/amd64/x86_64/' \ - | sed 's/^arm.*$$/arm/') + | sed 's/^arm.*$$/arm/' \ + | sed 's/aarch64/arm64/') build-platform := \ $(shell uname -s | tr [:upper:] [:lower:] \ | sed \ - -e 's/^mingw32.*$$/mingw32/' \ + -e 's/^mingw32.*$$/mingw32/' \ -e 's/^cygwin.*$$/cygwin/' \ -e 's/^darwin.*$$/macosx/') @@ -62,8 +63,8 @@ ifeq ($(filter compile interpret,$(process)),) x := $(error "'$(process)' is not a valid process (choose one of: compile interpret)") endif -ifeq ($(filter x86_64 i386 arm,$(arch)),) - x := $(error "'$(arch)' is not a supported architecture (choose one of: x86_64 i386 arm)") +ifeq ($(filter x86_64 i386 arm arm64,$(arch)),) + x := $(error "'$(arch)' is not a supported architecture (choose one of: x86_64 i386 arm arm64)") endif ifeq ($(platform),darwin) @@ -79,8 +80,8 @@ ifeq ($(filter linux windows macosx ios freebsd,$(platform)),) endif ifeq ($(platform),macosx) - ifeq ($(arch),arm) - x := $(error "please use 'arch=arm' 'platform=ios' to build for ios-arm") + ifneq ($(filter arm arm64,$(arch),) + x := $(error "please use 'arch=arm' or 'arch=arm64' 'platform=ios' to build for ios-arm") endif endif @@ -454,15 +455,15 @@ cflags = $(build-cflags) common-lflags = -lm -lz ifeq ($(use-clang),true) - ifeq ($(build-kernel),darwin) - common-lflags += -Wl,-export_dynamic - else - ifneq ($(platform),windows) - common-lflags += -Wl,-E - else - common-lflags += -Wl,--export-all-symbols - endif - endif + ifeq ($(build-kernel),darwin) + common-lflags += -Wl,-export_dynamic + else + ifneq ($(platform),windows) + common-lflags += -Wl,-E + else + common-lflags += -Wl,--export-all-symbols + endif + endif endif build-lflags = -lz -lpthread -ldl @@ -520,30 +521,39 @@ codeimage-symbols = _binary_codeimage_bin_start:_binary_codeimage_bin_end developer-dir := $(shell if test -d /Developer/Platforms/$(target).platform/Developer/SDKs; then echo /Developer; \ else echo /Applications/Xcode.app/Contents/Developer; fi) -ifeq ($(arch),i386) +ifneq (,$(filter i386 arm,$(arch))) pointer-size = 4 endif -ifeq ($(arch),arm) +ifneq (,$(filter arm arm64,$(arch))) asm = arm - pointer-size = 4 ifneq ($(platform),ios) - no-psabi = -Wno-psabi - cflags += -marm $(no-psabi) + ifneq ($(arch),arm64) + no-psabi = -Wno-psabi + cflags += -marm $(no-psabi) - # By default, assume we can't use armv7-specific instructions on - # non-iOS platforms. Ideally, we'd detect this at runtime. - armv6=true + # By default, assume we can't use armv7-specific instructions on + # non-iOS platforms. Ideally, we'd detect this at runtime. + armv6=true + endif endif ifneq ($(arch),$(build-arch)) ifneq ($(kernel),darwin) - cxx = arm-linux-gnueabi-g++ - cc = arm-linux-gnueabi-gcc - ar = arm-linux-gnueabi-ar - ranlib = arm-linux-gnueabi-ranlib - strip = arm-linux-gnueabi-strip + ifeq ($(arch),arm64) + cxx = aarch64-linux-gnu-g++ + cc = aarch64-linux-gnu-gcc + ar = aarch64-linux-gnu-ar + ranlib = aarch64-linux-gnu-ranlib + strip = aarch64-linux-gnu-strip + else + cxx = arm-linux-gnueabi-g++ + cc = arm-linux-gnueabi-gcc + ar = arm-linux-gnueabi-ar + ranlib = arm-linux-gnueabi-ranlib + strip = arm-linux-gnueabi-strip + endif endif endif endif @@ -682,7 +692,7 @@ ifeq ($(kernel),darwin) sdk-dir = $(platform-dir)/Developer/SDKs mac-version := $(shell \ - if test -d $(sdk-dir)/MacOSX10.9.sdk; then echo 10.9; \ + if test -d $(sdk-dir)/MacOSX10.9.sdk; then echo 10.9; \ elif test -d $(sdk-dir)/MacOSX10.8.sdk; then echo 10.8; \ elif test -d $(sdk-dir)/MacOSX10.7.sdk; then echo 10.7; \ elif test -d $(sdk-dir)/MacOSX10.6.sdk; then echo 10.6; \ @@ -721,7 +731,11 @@ ifeq ($(kernel),darwin) else target = iPhoneOS sdk = iphoneos$(ios-version) - arch-flag = -arch armv7 + ifeq ($(arch),arm) + arch-flag = -arch armv7 + else + arch-flag = -arch arm64 + endif release = Release-iphoneos endif @@ -729,7 +743,7 @@ ifeq ($(kernel),darwin) sdk-dir = $(platform-dir)/Developer/SDKs ios-version := $(shell \ - if test -d $(sdk-dir)/$(target)8.0.sdk; then echo 8.0; \ + if test -d $(sdk-dir)/$(target)8.0.sdk; then echo 8.0; \ elif test -d $(sdk-dir)/$(target)7.1.sdk; then echo 7.1; \ elif test -d $(sdk-dir)/$(target)7.0.sdk; then echo 7.0; \ elif test -d $(sdk-dir)/$(target)6.1.sdk; then echo 6.1; \ @@ -822,7 +836,7 @@ ifeq ($(platform),windows) && echo i686-w64-mingw32- || echo x86_64-w64-mingw32-) cxx = $(prefix)g++ -m32 cc = $(prefix)gcc -m32 - dlltool = $(prefix)dlltool -mi386 --as-flags=--32 + dlltool = $(prefix)dlltool -mi386 --as-flags=--32 ar = $(prefix)ar ranlib = $(prefix)ranlib strip = $(prefix)strip --strip-all @@ -1234,7 +1248,7 @@ ifeq ($(process),compile) vm-sources += $(native-assembler-sources) endif ifeq ($(codegen-targets),all) - ifeq ($(arch),arm) + ifneq (,$(filter arm arm64,$(arch))) # The x86 jit has a dependency on the x86 assembly code, # and thus can't be successfully built on non-x86 platforms. vm-sources += $(native-assembler-sources) @@ -1255,7 +1269,7 @@ all-codegen-target-objects = $(call cpp-objects,$(all-codegen-target-sources),$( vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(build)) vm-objects = $(vm-cpp-objects) $(vm-asm-objects) -heapwalk-sources = $(src)/heapwalk.cpp +heapwalk-sources = $(src)/heapwalk.cpp heapwalk-objects = \ $(call cpp-objects,$(heapwalk-sources),$(src),$(build)) @@ -1511,6 +1525,10 @@ ifeq ($(target-arch),arm) cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_ARM endif +ifeq ($(target-arch),arm64) + cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_ARM64 +endif + ifeq ($(target-format),elf) cflags += -DAVIAN_TARGET_FORMAT=AVIAN_FORMAT_ELF endif @@ -1639,7 +1657,7 @@ $(classpath-dep): $(classpath-sources) $(classpath-jar-dep) classes="$(shell $(MAKE) -s --no-print-directory build=$(build) \ $(classpath-classes))"; if [ -n "$${classes}" ]; then \ $(javac) -source 1.6 -target 1.6 \ - -d $(classpath-build) -bootclasspath $(boot-classpath) \ + -d $(classpath-build) -bootclasspath $(boot-classpath) \ $${classes}; fi @touch $(@) @@ -1703,7 +1721,7 @@ $(build)/android.dep: $(luni-javas) $(dalvik-javas) $(libart-javas) \ $(build)/android/java/security/security.properties chmod +w $(build)/android/java/security/security.properties cp -r $(build)/android/* $(classpath-build) - @touch $(@) + @touch $(@) $(test-build)/%.class: $(test)/%.java @echo $(<) @@ -1714,7 +1732,7 @@ $(test-dep): $(test-sources) $(test-library) files="$(shell $(MAKE) -s --no-print-directory build=$(build) $(test-classes))"; \ if test -n "$${files}"; then \ $(javac) -source 1.6 -target 1.6 \ - -classpath $(test-build) -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \ + -classpath $(test-build) -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \ fi $(javac) -source 1.2 -target 1.1 -XDjsrlimit=0 -d $(test-build) \ -bootclasspath $(boot-classpath) test/Subroutine.java @@ -1726,7 +1744,7 @@ $(test-extra-dep): $(test-extra-sources) files="$(shell $(MAKE) -s --no-print-directory build=$(build) $(test-extra-classes))"; \ if test -n "$${files}"; then \ $(javac) -source 1.6 -target 1.6 \ - -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \ + -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \ fi @touch $(@) @@ -1808,7 +1826,7 @@ ifdef mt endif else $(dlltool) -z $(addsuffix .def,$(basename $(@))) $(^) - $(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@))) + $(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@))) $(ld) $(addsuffix .exp,$(basename $(@))) $(^) \ $(lflags) $(bootimage-lflags) -o $(@) endif diff --git a/src/arm.S b/src/arm.S index 551fd85bf7..5d33b2cb58 100644 --- a/src/arm.S +++ b/src/arm.S @@ -10,7 +10,7 @@ details. */ #include "avian/types.h" - + .text #define LOCAL(x) .L##x @@ -18,9 +18,137 @@ #ifdef __APPLE__ # define GLOBAL(x) _##x #else -# define GLOBAL(x) x +# define GLOBAL(x) x #endif +#ifdef __aarch64__ + +.globl GLOBAL(vmNativeCall) +.align 2 +GLOBAL(vmNativeCall): + // arguments: + // x0 -> x19 : function + // w1 -> w20 : stackTotal + // x2 : memoryTable + // w3 : memoryCount + // x4 -> x21 : gprTable + // x5 -> x22 : vfpTable + // w6 -> w23 : returnType + + // allocate frame + stp x29, x30, [sp,#-64]! + + // save callee-saved register values so we can clobber them + stp x19, x20, [sp,#16] + stp x21, x22, [sp,#32] + str x23, [sp,#48] + + // move arguments into callee-saved registers + mov x19, x0 + mov w20, w1 + mov x21, x4 + mov x22, x5 + mov w23, w6 + + // setup stack arguments if necessary + sub sp, sp, w20 // allocate stack + mov x9, sp +LOCAL(loop): + cmp w3, wzr + b.eq LOCAL(populateGPRs) + ldr x0, [x2], #8 + str x0, [x9], #8 + sub w3, w3, #8 + b LOCAL(loop) + +LOCAL(populateGPRs): + cmp x21, xzr + b.eq LOCAL(populateVFPs) + ldp x0, x1, [x21] + ldp x2, x3, [x21,#16] + ldp x4, x5, [x21,#32] + ldp x6, x7, [x21,#48] + +LOCAL(populateVFPs): + cmp x22, xzr + b.eq LOCAL(doCall) + ldp d0, d1, [x22] + ldp d2, d3, [x22,#16] + ldp d4, d5, [x22,#32] + ldp d6, d7, [x22,#48] + +LOCAL(doCall): + blr x19 // call function + add sp, sp, w20 // deallocate stack + + cmp w23,#FLOAT_TYPE + bne LOCAL(double) + fmov w0,s0 + b LOCAL(exit) + +LOCAL(double): + cmp w23,#DOUBLE_TYPE + bne LOCAL(exit) + fmov x0,d0 + +LOCAL(exit): + ldp x19, x20, [sp,#16] + ldp x21, x22, [sp,#32] + ldr x23, [sp,#48] + ldp x29, x30, [sp],#64 + ret + +.globl GLOBAL(vmJump) +.align 2 +GLOBAL(vmJump): + mov x30, x0 + mov x0, x4 + mov x1, x5 + mov sp, x2 + mov x19, x3 + br x30 + +#define CHECKPOINT_THREAD 8 +#define CHECKPOINT_STACK 48 + +.globl GLOBAL(vmRun) +.align 2 +GLOBAL(vmRun): + // x0: function + // x1: arguments + // x2: checkpoint + + // allocate frame + stp x29, x30, [sp,#-96]! + + // save callee-saved register values + stp x19, x20, [sp,#16] + stp x21, x22, [sp,#32] + stp x23, x24, [sp,#48] + stp x25, x26, [sp,#64] + stp x27, x28, [sp,#80] + + mov x19, sp + str x19, [x2, #CHECKPOINT_STACK] + + mov x19, x0 + ldr x0, [x2, #CHECKPOINT_THREAD] + + blr x19 + +.globl GLOBAL(vmRun_returnAddress) +.align 2 +GLOBAL(vmRun_returnAddress): + ldp x19, x20, [sp,#16] + ldp x21, x22, [sp,#32] + ldp x23, x24, [sp,#48] + ldp x25, x26, [sp,#64] + ldp x27, x28, [sp,#80] + ldp x29, x30, [sp],#96 + br x30 + +#elif defined __arm__ + .globl GLOBAL(vmNativeCall) .align 2 GLOBAL(vmNativeCall): @@ -83,9 +211,9 @@ LOCAL(loop): LOCAL(double): cmp r8,#DOUBLE_TYPE bne LOCAL(exit) - fmrrd r0,r1,d0 + fmrrd r0,r1,d0 #endif - + LOCAL(exit): ldmfd sp!, {r4-r8, pc} // restore non-volatile regs and return @@ -111,7 +239,7 @@ GLOBAL(vmRun): stmfd sp!, {r4-r11, lr} // align stack sub sp, sp, #12 - + str sp, [r2, #CHECKPOINT_STACK] mov r12, r0 @@ -130,3 +258,5 @@ GLOBAL(vmRun_returnAddress): add sp, sp, #12 ldmfd sp!, {r4-r11, lr} bx lr + +#endif // __arm__ diff --git a/src/avian/arch.h b/src/avian/arch.h index cf717b0369..b799ca50cb 100644 --- a/src/avian/arch.h +++ b/src/avian/arch.h @@ -43,7 +43,7 @@ inline void compileTimeMemoryBarrier() #if (defined ARCH_x86_32) || (defined ARCH_x86_64) #include "x86.h" -#elif defined ARCH_arm +#elif (defined ARCH_arm) || (defined ARCH_arm64) #include "arm.h" #else #error unsupported architecture diff --git a/src/avian/arm.h b/src/avian/arm.h index e44848c924..9fbc83c474 100644 --- a/src/avian/arm.h +++ b/src/avian/arm.h @@ -53,10 +53,17 @@ #define THREAD_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_IP]) #define LINK_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_LR]) #else +#ifdef ARCH_arm #define IP_REGISTER(context) (context->uc_mcontext.arm_pc) #define STACK_REGISTER(context) (context->uc_mcontext.arm_sp) #define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip) #define LINK_REGISTER(context) (context->uc_mcontext.arm_lr) +#else +#define IP_REGISTER(context) (context->uc_mcontext.pc) +#define STACK_REGISTER(context) (context->uc_mcontext.sp) +#define THREAD_REGISTER(context) (context->uc_mcontext.regs[19]) +#define LINK_REGISTER(context) (context->uc_mcontext.regs[30]) +#endif #endif #define VA_LIST(x) (&(x)) @@ -76,7 +83,7 @@ inline void trap() #ifdef _MSC_VER __debugbreak(); #else - asm("bkpt"); + asm("brk 0"); #endif } @@ -162,6 +169,8 @@ inline bool atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_) old, new_, reinterpret_cast(p)); #elif(defined __QNX__) return old == _smp_cmpxchg(p, old, new_); +#elif (defined ARCH_arm64) + return __sync_bool_compare_and_swap(p, old, new_); #else int r = __kernel_cmpxchg( static_cast(old), static_cast(new_), reinterpret_cast(p)); @@ -169,10 +178,22 @@ inline bool atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_) #endif } +#ifdef ARCH_arm64 +inline bool atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_) +{ + return __sync_bool_compare_and_swap(p, old, new_); +} + +inline bool atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_) +{ + return atomicCompareAndSwap64(reinterpret_cast(p), old, new_); +} +#else inline bool atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_) { return atomicCompareAndSwap32(reinterpret_cast(p), old, new_); } +#endif inline uint64_t dynamicCall(void* function, uintptr_t* arguments, @@ -181,17 +202,17 @@ inline uint64_t dynamicCall(void* function, unsigned argumentsSize UNUSED, unsigned returnType) { -#ifdef __APPLE__ +#if (defined __APPLE__) || (defined ARCH_arm64) const unsigned Alignment = 1; #else const unsigned Alignment = 2; #endif - const unsigned GprCount = 4; + const unsigned GprCount = BytesPerWord; uintptr_t gprTable[GprCount]; unsigned gprIndex = 0; - const unsigned VfpCount = 16; + const unsigned VfpCount = BytesPerWord == 8 ? 8 : 16; uintptr_t vfpTable[VfpCount]; unsigned vfpIndex = 0; unsigned vfpBackfillIndex UNUSED = 0; @@ -206,7 +227,7 @@ inline uint64_t dynamicCall(void* function, for (unsigned ati = 0; ati < argumentCount; ++ati) { switch (argumentTypes[ati]) { case DOUBLE_TYPE: -#if defined(__ARM_PCS_VFP) +#if (defined __ARM_PCS_VFP) || (defined ARCH_arm64) { if (vfpIndex + Alignment <= VfpCount) { if (vfpIndex % Alignment) { diff --git a/src/avian/common.h b/src/avian/common.h index ac05cef999..96f4498f54 100644 --- a/src/avian/common.h +++ b/src/avian/common.h @@ -116,6 +116,8 @@ typedef intptr_t intptr_alias_t; #define ARCH_x86_64 #elif defined __arm__ #define ARCH_arm +#elif defined __aarch64__ +#define ARCH_arm64 #else #error "unsupported architecture" #endif @@ -184,7 +186,7 @@ typedef intptr_t __attribute__((__may_alias__)) intptr_alias_t; #error "Unsupported architecture" #endif #endif - + #ifdef PLATFORM_WINDOWS #define SO_PREFIX "" #else diff --git a/src/avian/environment.h b/src/avian/environment.h index 8df211b559..d95b40617c 100644 --- a/src/avian/environment.h +++ b/src/avian/environment.h @@ -28,5 +28,6 @@ #define AVIAN_ARCH_X86 (1 << 8) #define AVIAN_ARCH_X86_64 (2 << 8) #define AVIAN_ARCH_ARM (3 << 8) +#define AVIAN_ARCH_ARM64 (4 << 8) #endif diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index f6d0a9d7fa..ed639acac6 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -52,10 +52,17 @@ inline int fpr32(lir::Register* reg) return fpr64(reg) << 1; } +#ifdef ARCH_arm64 +const int ThreadRegister = 19; +const int StackRegister = 31; +const int LinkRegister = 30; +const int ProgramCounter = 0xFF; // i.e. unaddressable +#else const int ThreadRegister = 8; const int StackRegister = 13; const int LinkRegister = 14; const int ProgramCounter = 15; +#endif } // namespace arm } // namespace codegen diff --git a/src/codegen/targets.cpp b/src/codegen/targets.cpp index e981e8a497..fff55d3b35 100644 --- a/src/codegen/targets.cpp +++ b/src/codegen/targets.cpp @@ -30,7 +30,8 @@ Architecture* makeArchitectureNative(vm::System* system, #elif(AVIAN_TARGET_ARCH == AVIAN_ARCH_X86) \ || (AVIAN_TARGET_ARCH == AVIAN_ARCH_X86_64) return makeArchitectureX86(system, useNativeFeatures); -#elif AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM +#elif (AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM) \ + || (AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64) return makeArchitectureArm(system, useNativeFeatures); #else #error "Unsupported codegen target" diff --git a/src/tools/object-writer/elf.cpp b/src/tools/object-writer/elf.cpp index 2733ee0225..46c4e62936 100644 --- a/src/tools/object-writer/elf.cpp +++ b/src/tools/object-writer/elf.cpp @@ -49,6 +49,7 @@ #define EM_386 3 #define EM_X86_64 62 #define EM_ARM 40 +#define EM_AARCH64 183 #define SHT_PROGBITS 1 #define SHT_SYMTAB 2 @@ -129,6 +130,8 @@ unsigned getElfPlatform(PlatformInfo::Architecture arch) return EM_386; case PlatformInfo::Arm: return EM_ARM; + case PlatformInfo::Arm64: + return EM_AARCH64; default: return ~0; } @@ -398,6 +401,7 @@ class ElfPlatform : public Platform { ElfPlatform elfX86Platform(PlatformInfo::x86); ElfPlatform elfArmPlatform(PlatformInfo::Arm); +ElfPlatform elfArm64Platform(PlatformInfo::Arm64); ElfPlatform elfX86_64Platform(PlatformInfo::x86_64); } // namespace diff --git a/src/tools/object-writer/tools.cpp b/src/tools/object-writer/tools.cpp index ad736efd24..869cc6c249 100644 --- a/src/tools/object-writer/tools.cpp +++ b/src/tools/object-writer/tools.cpp @@ -115,6 +115,8 @@ PlatformInfo::Architecture PlatformInfo::archFromString(const char* arch) return Architecture::x86_64; } else if (strcmp(arch, "arm") == 0) { return Architecture::Arm; + } else if (strcmp(arch, "arm64") == 0) { + return Architecture::Arm64; } else { return Architecture::UnknownArch; } From 2762f011990c4c384677b0b99f16d2641d6d5e36 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 26 Nov 2014 20:05:46 -0700 Subject: [PATCH 02/70] fix #373 (makefile syntax on mac) --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index 11f1aa74c4..5543c0e110 100755 --- a/makefile +++ b/makefile @@ -80,7 +80,7 @@ ifeq ($(filter linux windows macosx ios freebsd,$(platform)),) endif ifeq ($(platform),macosx) - ifneq ($(filter arm arm64,$(arch),) + ifneq ($(filter arm arm64,$(arch)),) x := $(error "please use 'arch=arm' or 'arch=arm64' 'platform=ios' to build for ios-arm") endif endif From 29f32859da9e9060c232a16ed997ad5d10a58f94 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Fri, 5 Dec 2014 13:25:10 -0700 Subject: [PATCH 03/70] add -r option to docker/build.sh for executing as root --- docker/build.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docker/build.sh b/docker/build.sh index bdeb0dd6fa..b67b599f1d 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -8,6 +8,8 @@ if test $# -eq 0; then exit 1 fi +THE_USER="-u $(id -u "${USER}")" + while test $# -gt 1 ; do key="$1" case $key in @@ -16,6 +18,10 @@ while test $# -gt 1 ; do CONTAINER="$1" shift ;; + -r|--root) + shift + THE_USER= + ;; --) shift break @@ -32,4 +38,4 @@ fi DIR=$(cd $(dirname "$0") && cd .. && pwd) -docker run --rm -i -t -v "${DIR}":/var/avian -u $(id -u "${USER}") "${CONTAINER}" "${@}" +docker run --rm -i -t -v "${DIR}":/var/avian ${THE_USER} "${CONTAINER}" "${@}" From 56d0bd48002a76510da21cbe4436d903acdee1e8 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Fri, 5 Dec 2014 12:58:10 -0700 Subject: [PATCH 04/70] Add arm64 dockerfile --- docker/arm64/Dockerfile | 71 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 docker/arm64/Dockerfile diff --git a/docker/arm64/Dockerfile b/docker/arm64/Dockerfile new file mode 100644 index 0000000000..c39413a31e --- /dev/null +++ b/docker/arm64/Dockerfile @@ -0,0 +1,71 @@ +FROM joshuawarner32/avian-build +MAINTAINER Joshua Warner, joshuawarner32@gmail.com + +RUN dpkg --add-architecture arm64 && \ + apt-get update && \ + mkdir -p /opt/arm64 && \ + apt-get download libc6-dev:arm64 \ + linux-headers-3.16.0-4-all-arm64:arm64 \ + linux-libc-dev:arm64 \ + libc6:arm64 \ + zlib1g-dev:arm64 \ + zlib1g:arm64 && \ + for x in *.deb; do \ + dpkg -x $x /opt/arm64; \ + done && \ + rm *.deb && \ + apt-get install -y \ + wget \ + libgmp-dev \ + libmpfr-dev \ + libmpc-dev \ + libisl-dev && \ + apt-get clean all && \ + for x in $(find /opt/arm64 -type l); do \ + r=$(readlink "$x" | sed 's,^/,/opt/arm64/,g'); \ + rm "$x"; \ + ln -s "$r" "$x"; \ + done + +RUN mkdir -p /var/src + +# Build & install binutils +RUN wget ftp://sourceware.org/pub/binutils/snapshots/binutils-2.23.91.tar.bz2 -O /var/src/binutils.tar.bz2 && \ + cd /var/src/ && tar -xjf binutils.tar.bz2 && rm binutils.tar.bz2 && \ + cd /var/src/binutils* && \ + mkdir build && \ + cd build && \ + ../configure \ + --target=aarch64-linux-gnu \ + --prefix=/opt/arm64 \ + --disable-multilib \ + --program-prefix=aarch64-linux-gnu- \ + --with-sysroot=/opt/arm64 \ + --with-headers=/opt/arm64/usr/include \ + --disable-werror && \ + make && \ + make install && \ + cd /var/src && \ + rm -rf * + +# build & install gcc +RUN wget http://www.netgull.com/gcc/releases/gcc-4.8.2/gcc-4.8.2.tar.bz2 -O /var/src/gcc.tar.bz2 && \ + cd /var/src/ && tar -xjf gcc.tar.bz2 && rm gcc.tar.bz2 && \ + cd /var/src/gcc* && \ + mkdir build && \ + cd build && \ + ../configure \ + --target=aarch64-linux-gnu \ + --enable-languages=c,c++ \ + --prefix=/opt/arm64 \ + --disable-multilib \ + --program-prefix=aarch64-linux-gnu- \ + --with-sysroot=/opt/arm64 \ + --with-headers=/opt/arm64/usr/include \ + --disable-werror && \ + make && \ + make install && \ + cd /var/src && \ + rm -rf * + +ENV PATH $PATH:/opt/arm64/bin From a2b4d3cb7c91daba4a5b6fd6fa19f81afd7a5963 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 4 Dec 2014 14:47:26 -0700 Subject: [PATCH 05/70] add support for 8.1 SDK --- makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index 5543c0e110..cbaa4ec42a 100755 --- a/makefile +++ b/makefile @@ -743,7 +743,8 @@ ifeq ($(kernel),darwin) sdk-dir = $(platform-dir)/Developer/SDKs ios-version := $(shell \ - if test -d $(sdk-dir)/$(target)8.0.sdk; then echo 8.0; \ + if test -d $(sdk-dir)/$(target)8.1.sdk; then echo 8.1; \ + elif test -d $(sdk-dir)/$(target)8.0.sdk; then echo 8.0; \ elif test -d $(sdk-dir)/$(target)7.1.sdk; then echo 7.1; \ elif test -d $(sdk-dir)/$(target)7.0.sdk; then echo 7.0; \ elif test -d $(sdk-dir)/$(target)6.1.sdk; then echo 6.1; \ From ac72aa8b91b30e11227c3585f0d7fcc443fdaa2b Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 4 Dec 2014 12:18:02 -0700 Subject: [PATCH 06/70] split low/high register mask in OperandMask --- include/avian/codegen/architecture.h | 22 ++++-- src/codegen/compiler.cpp | 4 +- src/codegen/compiler/event.cpp | 2 +- src/codegen/compiler/site.h | 4 +- src/codegen/target/arm/assembler.cpp | 42 +++++------ src/codegen/target/x86/assembler.cpp | 104 +++++++++++++-------------- unittest/codegen/assembler-test.cpp | 2 +- 7 files changed, 97 insertions(+), 83 deletions(-) diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index b1cd7e8013..3533f5ed26 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -32,14 +32,28 @@ class RegisterFile; class OperandMask { public: uint8_t typeMask; - uint64_t registerMask; + uint64_t lowRegisterMask; + uint64_t highRegisterMask; - OperandMask(uint8_t typeMask, uint64_t registerMask) - : typeMask(typeMask), registerMask(registerMask) + OperandMask(uint8_t typeMask, + uint64_t lowRegisterMask, + uint64_t highRegisterMask) + : typeMask(typeMask), + lowRegisterMask(lowRegisterMask), + highRegisterMask(highRegisterMask) { } - OperandMask() : typeMask(~0), registerMask(~static_cast(0)) + // TEMPORARY! + OperandMask(uint8_t typeMask, + uint64_t registerMask) + : typeMask(typeMask), + lowRegisterMask(registerMask), + highRegisterMask(registerMask >> 32) + { + } + + OperandMask() : typeMask(~0), lowRegisterMask(~static_cast(0)), highRegisterMask(~static_cast(0)) { } }; diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index fbb64bf923..eabe367586 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -874,14 +874,14 @@ void maybeMove(Context* c, c->arch->planSource(op, dstSize, src, dstSize, &thunk); if (isGeneralValue(srcValue)) { - src.registerMask &= c->regFile->generalRegisters.mask; + src.lowRegisterMask &= c->regFile->generalRegisters.mask; } assertT(c, thunk == 0); assertT(c, dstMask.typeMask & src.typeMask & (1 << lir::RegisterOperand)); Site* tmpTarget - = freeRegisterSite(c, dstMask.registerMask & src.registerMask); + = freeRegisterSite(c, dstMask.registerMask & src.lowRegisterMask); srcValue->source->freeze(c, srcValue); diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 7bb0257f3f..9668897547 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -445,7 +445,7 @@ class CallEvent : public Event { this->addRead( c, address, - SiteMask(op.typeMask, registerMask & op.registerMask, AnyFrameIndex)); + SiteMask(op.typeMask, registerMask & op.lowRegisterMask, AnyFrameIndex)); } Stack* stack = stackBefore; diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 3f93d1f5dd..648c0942b8 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -48,12 +48,12 @@ class SiteMask { static SiteMask lowPart(const OperandMask& mask) { - return SiteMask(mask.typeMask, mask.registerMask, AnyFrameIndex); + return SiteMask(mask.typeMask, mask.lowRegisterMask, AnyFrameIndex); } static SiteMask highPart(const OperandMask& mask) { - return SiteMask(mask.typeMask, mask.registerMask >> 32, AnyFrameIndex); + return SiteMask(mask.typeMask, mask.lowRegisterMask >> 32, AnyFrameIndex); } uint8_t typeMask; diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 7de408deba..c080bdad90 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -402,7 +402,7 @@ class MyArchitecture : public Architecture { bool* thunk) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); - aMask.registerMask = ~static_cast(0); + aMask.lowRegisterMask = ~static_cast(0); *thunk = false; } @@ -414,12 +414,12 @@ class MyArchitecture : public Architecture { { *thunk = false; aMask.typeMask = ~0; - aMask.registerMask = GPR_MASK64; + aMask.lowRegisterMask = GPR_MASK64; switch (op) { case lir::Negate: aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = GPR_MASK64; + aMask.lowRegisterMask = GPR_MASK64; break; case lir::Absolute: @@ -432,7 +432,7 @@ class MyArchitecture : public Architecture { case lir::Float2Float: if (vfpSupported()) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = FPR_MASK64; + aMask.lowRegisterMask = FPR_MASK64; } else { *thunk = true; } @@ -445,7 +445,7 @@ class MyArchitecture : public Architecture { // cases properly. if (false && vfpSupported() && bSize == 4) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = FPR_MASK64; + aMask.lowRegisterMask = FPR_MASK64; } else { *thunk = true; } @@ -454,7 +454,7 @@ class MyArchitecture : public Architecture { case lir::Int2Float: if (vfpSupported() && aSize == 4) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = GPR_MASK64; + aMask.lowRegisterMask = GPR_MASK64; } else { *thunk = true; } @@ -472,12 +472,12 @@ class MyArchitecture : public Architecture { OperandMask& bMask) { bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - bMask.registerMask = GPR_MASK64; + bMask.lowRegisterMask = GPR_MASK64; switch (op) { case lir::Negate: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = GPR_MASK64; + bMask.lowRegisterMask = GPR_MASK64; break; case lir::FloatAbsolute: @@ -486,12 +486,12 @@ class MyArchitecture : public Architecture { case lir::Float2Float: case lir::Int2Float: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = FPR_MASK64; + bMask.lowRegisterMask = FPR_MASK64; break; case lir::Float2Int: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = GPR_MASK64; + bMask.lowRegisterMask = GPR_MASK64; break; case lir::Move: @@ -511,21 +511,21 @@ class MyArchitecture : public Architecture { const OperandMask& dstMask) { srcMask.typeMask = ~0; - srcMask.registerMask = ~static_cast(0); + srcMask.lowRegisterMask = ~static_cast(0); tmpMask.typeMask = 0; - tmpMask.registerMask = 0; + tmpMask.lowRegisterMask = 0; if (dstMask.typeMask & (1 << lir::MemoryOperand)) { // can't move directly from memory or constant to memory srcMask.typeMask = 1 << lir::RegisterOperand; tmpMask.typeMask = 1 << lir::RegisterOperand; - tmpMask.registerMask = GPR_MASK64; + tmpMask.lowRegisterMask = GPR_MASK64; } else if (vfpSupported() && dstMask.typeMask & 1 << lir::RegisterOperand - && dstMask.registerMask & FPR_MASK) { + && dstMask.lowRegisterMask & FPR_MASK) { srcMask.typeMask = tmpMask.typeMask = 1 << lir::RegisterOperand | 1 << lir::MemoryOperand; - tmpMask.registerMask = ~static_cast(0); + tmpMask.lowRegisterMask = ~static_cast(0); } } @@ -538,10 +538,10 @@ class MyArchitecture : public Architecture { bool* thunk) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); - aMask.registerMask = GPR_MASK64; + aMask.lowRegisterMask = GPR_MASK64; bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = GPR_MASK64; + bMask.lowRegisterMask = GPR_MASK64; *thunk = false; @@ -573,7 +573,7 @@ class MyArchitecture : public Architecture { case lir::FloatDivide: if (vfpSupported()) { aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = bMask.registerMask = FPR_MASK64; + aMask.lowRegisterMask = bMask.lowRegisterMask = FPR_MASK64; } else { *thunk = true; } @@ -591,7 +591,7 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (vfpSupported()) { aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = bMask.registerMask = FPR_MASK64; + aMask.lowRegisterMask = bMask.lowRegisterMask = FPR_MASK64; } else { *thunk = true; } @@ -612,10 +612,10 @@ class MyArchitecture : public Architecture { { if (isBranch(op)) { cMask.typeMask = (1 << lir::ConstantOperand); - cMask.registerMask = 0; + cMask.lowRegisterMask = 0; } else { cMask.typeMask = (1 << lir::RegisterOperand); - cMask.registerMask = bMask.registerMask; + cMask.lowRegisterMask = bMask.lowRegisterMask; } } diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index e9ada91b2e..1b88e15bbe 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -512,7 +512,7 @@ class MyArchitecture : public Architecture { unsigned bSize, bool* thunk) { - aMask.registerMask = GeneralRegisterMask + aMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); *thunk = false; @@ -520,14 +520,14 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Negate: aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = (static_cast(1) << (rdx + 32)) + aMask.lowRegisterMask = (static_cast(1) << (rdx + 32)) | (static_cast(1) << rax); break; case lir::Absolute: if (aSize <= TargetBytesPerWord) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = (static_cast(1) << rax); + aMask.lowRegisterMask = (static_cast(1) << rax); } else { *thunk = true; } @@ -536,7 +536,7 @@ class MyArchitecture : public Architecture { case lir::FloatAbsolute: if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = (static_cast(FloatRegisterMask) << 32) + aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { *thunk = true; @@ -547,7 +547,7 @@ class MyArchitecture : public Architecture { // floatNegateRR does not support doubles if (useSSE(&c) and aSize == 4 and bSize == 4) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = FloatRegisterMask; + aMask.lowRegisterMask = FloatRegisterMask; } else { *thunk = true; } @@ -557,7 +557,7 @@ class MyArchitecture : public Architecture { if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.registerMask = (static_cast(FloatRegisterMask) << 32) + aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { *thunk = true; @@ -568,7 +568,7 @@ class MyArchitecture : public Architecture { if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.registerMask = (static_cast(FloatRegisterMask) << 32) + aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { *thunk = true; @@ -583,7 +583,7 @@ class MyArchitecture : public Architecture { if (false and useSSE(&c) and bSize <= TargetBytesPerWord) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.registerMask = (static_cast(FloatRegisterMask) << 32) + aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { *thunk = true; @@ -594,7 +594,7 @@ class MyArchitecture : public Architecture { if (useSSE(&c) and aSize <= TargetBytesPerWord) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.registerMask + aMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } else { @@ -604,7 +604,7 @@ class MyArchitecture : public Architecture { case lir::Move: aMask.typeMask = ~0; - aMask.registerMask = ~static_cast(0); + aMask.lowRegisterMask = ~static_cast(0); if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { @@ -612,13 +612,13 @@ class MyArchitecture : public Architecture { | (1 << lir::MemoryOperand); const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - aMask.registerMask = (static_cast(mask) << 32) | mask; + aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; } else if (aSize == 1 or bSize == 1) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); - aMask.registerMask = (static_cast(mask) << 32) | mask; + aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; } } break; @@ -635,23 +635,23 @@ class MyArchitecture : public Architecture { OperandMask& bMask) { bMask.typeMask = ~0; - bMask.registerMask = GeneralRegisterMask + bMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); switch (op) { case lir::Absolute: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = (static_cast(1) << rax); + bMask.lowRegisterMask = (static_cast(1) << rax); break; case lir::FloatAbsolute: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = aMask.registerMask; + bMask.lowRegisterMask = aMask.lowRegisterMask; break; case lir::Negate: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = aMask.registerMask; + bMask.lowRegisterMask = aMask.lowRegisterMask; break; case lir::FloatNegate: @@ -659,7 +659,7 @@ class MyArchitecture : public Architecture { case lir::Float2Float: case lir::Int2Float: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = (static_cast(FloatRegisterMask) << 32) + bMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; break; @@ -671,16 +671,16 @@ class MyArchitecture : public Architecture { if (aMask.typeMask & ((1 << lir::MemoryOperand) | 1 << lir::AddressOperand)) { bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = GeneralRegisterMask + bMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32) | FloatRegisterMask; } else if (aMask.typeMask & (1 << lir::RegisterOperand)) { bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - if (aMask.registerMask & FloatRegisterMask) { - bMask.registerMask = FloatRegisterMask; + if (aMask.lowRegisterMask & FloatRegisterMask) { + bMask.lowRegisterMask = FloatRegisterMask; } else { - bMask.registerMask + bMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } @@ -691,12 +691,12 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { - bMask.registerMask = (static_cast(1) << (rdx + 32)) + bMask.lowRegisterMask = (static_cast(1) << (rdx + 32)) | (static_cast(1) << rax); } else if (aSize == 1 or bSize == 1) { const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); - bMask.registerMask = (static_cast(mask) << 32) | mask; + bMask.lowRegisterMask = (static_cast(mask) << 32) | mask; } } break; @@ -712,36 +712,36 @@ class MyArchitecture : public Architecture { const OperandMask& dstMask) { srcMask.typeMask = ~0; - srcMask.registerMask = ~static_cast(0); + srcMask.lowRegisterMask = ~static_cast(0); tmpMask.typeMask = 0; - tmpMask.registerMask = 0; + tmpMask.lowRegisterMask = 0; if (dstMask.typeMask & (1 << lir::MemoryOperand)) { // can't move directly from memory to memory srcMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); tmpMask.typeMask = 1 << lir::RegisterOperand; - tmpMask.registerMask + tmpMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } else if (dstMask.typeMask & (1 << lir::RegisterOperand)) { if (size > TargetBytesPerWord) { // can't move directly from FPR to GPR or vice-versa for // values larger than the GPR size - if (dstMask.registerMask & FloatRegisterMask) { - srcMask.registerMask + if (dstMask.lowRegisterMask & FloatRegisterMask) { + srcMask.lowRegisterMask = FloatRegisterMask | (static_cast(FloatRegisterMask) << 32); tmpMask.typeMask = 1 << lir::MemoryOperand; - } else if (dstMask.registerMask & GeneralRegisterMask) { - srcMask.registerMask + } else if (dstMask.lowRegisterMask & GeneralRegisterMask) { + srcMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); tmpMask.typeMask = 1 << lir::MemoryOperand; } } - if (dstMask.registerMask & FloatRegisterMask) { + if (dstMask.lowRegisterMask & FloatRegisterMask) { // can't move directly from constant to FPR srcMask.typeMask &= ~(1 << lir::ConstantOperand); if (size > TargetBytesPerWord) { @@ -749,7 +749,7 @@ class MyArchitecture : public Architecture { } else { tmpMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - tmpMask.registerMask + tmpMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } @@ -766,11 +766,11 @@ class MyArchitecture : public Architecture { bool* thunk) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); - aMask.registerMask = GeneralRegisterMask + aMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); bMask.typeMask = (1 << lir::RegisterOperand); - bMask.registerMask = GeneralRegisterMask + bMask.lowRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); *thunk = false; @@ -787,8 +787,8 @@ class MyArchitecture : public Architecture { const uint64_t mask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; - aMask.registerMask = mask; - bMask.registerMask = mask; + aMask.lowRegisterMask = mask; + bMask.lowRegisterMask = mask; } else { *thunk = true; } @@ -801,11 +801,11 @@ class MyArchitecture : public Architecture { case lir::Multiply: if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - aMask.registerMask = (static_cast(mask) << 32) | mask; - bMask.registerMask = (static_cast(1) << (rdx + 32)) | mask; + aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; + bMask.lowRegisterMask = (static_cast(1) << (rdx + 32)) | mask; } else { - aMask.registerMask = GeneralRegisterMask; - bMask.registerMask = GeneralRegisterMask; + aMask.lowRegisterMask = GeneralRegisterMask; + bMask.lowRegisterMask = GeneralRegisterMask; } break; @@ -814,8 +814,8 @@ class MyArchitecture : public Architecture { *thunk = true; } else { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - bMask.registerMask = 1 << rax; + aMask.lowRegisterMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); + bMask.lowRegisterMask = 1 << rax; } break; @@ -824,8 +824,8 @@ class MyArchitecture : public Architecture { *thunk = true; } else { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - bMask.registerMask = 1 << rax; + aMask.lowRegisterMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); + bMask.lowRegisterMask = 1 << rax; } break; @@ -834,13 +834,13 @@ class MyArchitecture : public Architecture { case lir::UnsignedShiftRight: { if (TargetBytesPerWord == 4 and bSize == 8) { const uint32_t mask = GeneralRegisterMask & ~(1 << rcx); - aMask.registerMask = (static_cast(mask) << 32) | mask; - bMask.registerMask = (static_cast(mask) << 32) | mask; + aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; + bMask.lowRegisterMask = (static_cast(mask) << 32) | mask; } else { - aMask.registerMask = (static_cast(GeneralRegisterMask) << 32) + aMask.lowRegisterMask = (static_cast(GeneralRegisterMask) << 32) | (static_cast(1) << rcx); const uint32_t mask = GeneralRegisterMask & ~(1 << rcx); - bMask.registerMask = (static_cast(mask) << 32) | mask; + bMask.lowRegisterMask = (static_cast(mask) << 32) | mask; } } break; @@ -856,10 +856,10 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.registerMask = (static_cast(FloatRegisterMask) << 32) + aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; bMask.typeMask = aMask.typeMask; - bMask.registerMask = aMask.registerMask; + bMask.lowRegisterMask = aMask.lowRegisterMask; } else { *thunk = true; } @@ -880,10 +880,10 @@ class MyArchitecture : public Architecture { { if (isBranch(op)) { cMask.typeMask = (1 << lir::ConstantOperand); - cMask.registerMask = 0; + cMask.lowRegisterMask = 0; } else { cMask.typeMask = (1 << lir::RegisterOperand); - cMask.registerMask = bMask.registerMask; + cMask.lowRegisterMask = bMask.lowRegisterMask; } } diff --git a/unittest/codegen/assembler-test.cpp b/unittest/codegen/assembler-test.cpp index f463b0c5b4..bffbe6daf6 100644 --- a/unittest/codegen/assembler-test.cpp +++ b/unittest/codegen/assembler-test.cpp @@ -79,6 +79,6 @@ TEST(ArchitecturePlan) (lir::UnaryOperation)op, vm::TargetBytesPerWord, mask, &thunk); assertFalse(thunk); assertNotEqual(static_cast(0), mask.typeMask); - assertNotEqual(static_cast(0), mask.registerMask); + assertNotEqual(static_cast(0), mask.lowRegisterMask); } } From 1110d3ff50ffe45617922a3260d2bd4c7d8c2f6e Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 4 Dec 2014 12:27:58 -0700 Subject: [PATCH 07/70] begin converting to setLowHighRegisterMasks --- include/avian/codegen/architecture.h | 5 ++ src/codegen/compiler/site.h | 2 +- src/codegen/target/arm/assembler.cpp | 45 +++++----- src/codegen/target/x86/assembler.cpp | 121 +++++++++++---------------- 4 files changed, 78 insertions(+), 95 deletions(-) diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index 3533f5ed26..e4fa825af3 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -56,6 +56,11 @@ class OperandMask { OperandMask() : typeMask(~0), lowRegisterMask(~static_cast(0)), highRegisterMask(~static_cast(0)) { } + + void setLowHighRegisterMasks(uint64_t lowRegisterMask, uint64_t highRegisterMask) { + this->lowRegisterMask = lowRegisterMask | (highRegisterMask << 32); + this->highRegisterMask = highRegisterMask; + } }; class Architecture { diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 648c0942b8..5c5e9daa35 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -53,7 +53,7 @@ class SiteMask { static SiteMask highPart(const OperandMask& mask) { - return SiteMask(mask.typeMask, mask.lowRegisterMask >> 32, AnyFrameIndex); + return SiteMask(mask.typeMask, mask.highRegisterMask, AnyFrameIndex); } uint8_t typeMask; diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index c080bdad90..8932c7ec83 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -402,7 +402,7 @@ class MyArchitecture : public Architecture { bool* thunk) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); - aMask.lowRegisterMask = ~static_cast(0); + aMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); *thunk = false; } @@ -414,12 +414,12 @@ class MyArchitecture : public Architecture { { *thunk = false; aMask.typeMask = ~0; - aMask.lowRegisterMask = GPR_MASK64; + aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); switch (op) { case lir::Negate: aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = GPR_MASK64; + aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; case lir::Absolute: @@ -432,7 +432,7 @@ class MyArchitecture : public Architecture { case lir::Float2Float: if (vfpSupported()) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = FPR_MASK64; + aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); } else { *thunk = true; } @@ -445,7 +445,7 @@ class MyArchitecture : public Architecture { // cases properly. if (false && vfpSupported() && bSize == 4) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = FPR_MASK64; + aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); } else { *thunk = true; } @@ -454,7 +454,7 @@ class MyArchitecture : public Architecture { case lir::Int2Float: if (vfpSupported() && aSize == 4) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = GPR_MASK64; + aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); } else { *thunk = true; } @@ -472,12 +472,12 @@ class MyArchitecture : public Architecture { OperandMask& bMask) { bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - bMask.lowRegisterMask = GPR_MASK64; + bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); switch (op) { case lir::Negate: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = GPR_MASK64; + bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; case lir::FloatAbsolute: @@ -486,12 +486,12 @@ class MyArchitecture : public Architecture { case lir::Float2Float: case lir::Int2Float: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = FPR_MASK64; + bMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); break; case lir::Float2Int: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = GPR_MASK64; + bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; case lir::Move: @@ -511,21 +511,21 @@ class MyArchitecture : public Architecture { const OperandMask& dstMask) { srcMask.typeMask = ~0; - srcMask.lowRegisterMask = ~static_cast(0); + srcMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); tmpMask.typeMask = 0; - tmpMask.lowRegisterMask = 0; + tmpMask.setLowHighRegisterMasks(0, 0); if (dstMask.typeMask & (1 << lir::MemoryOperand)) { // can't move directly from memory or constant to memory srcMask.typeMask = 1 << lir::RegisterOperand; tmpMask.typeMask = 1 << lir::RegisterOperand; - tmpMask.lowRegisterMask = GPR_MASK64; + tmpMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); } else if (vfpSupported() && dstMask.typeMask & 1 << lir::RegisterOperand && dstMask.lowRegisterMask & FPR_MASK) { srcMask.typeMask = tmpMask.typeMask = 1 << lir::RegisterOperand | 1 << lir::MemoryOperand; - tmpMask.lowRegisterMask = ~static_cast(0); + tmpMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); } } @@ -538,10 +538,10 @@ class MyArchitecture : public Architecture { bool* thunk) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); - aMask.lowRegisterMask = GPR_MASK64; + aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = GPR_MASK64; + bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); *thunk = false; @@ -572,8 +572,9 @@ class MyArchitecture : public Architecture { case lir::FloatMultiply: case lir::FloatDivide: if (vfpSupported()) { - aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = bMask.lowRegisterMask = FPR_MASK64; + bMask.typeMask = (1 << lir::RegisterOperand); + aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); + bMask = aMask; } else { *thunk = true; } @@ -590,8 +591,9 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatLessOrEqualOrUnordered: case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (vfpSupported()) { - aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = bMask.lowRegisterMask = FPR_MASK64; + aMask.typeMask = (1 << lir::RegisterOperand); + aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); + bMask = aMask; } else { *thunk = true; } @@ -612,10 +614,11 @@ class MyArchitecture : public Architecture { { if (isBranch(op)) { cMask.typeMask = (1 << lir::ConstantOperand); - cMask.lowRegisterMask = 0; + cMask.setLowHighRegisterMasks(0, 0); } else { cMask.typeMask = (1 << lir::RegisterOperand); cMask.lowRegisterMask = bMask.lowRegisterMask; + cMask.highRegisterMask = bMask.highRegisterMask; } } diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index 1b88e15bbe..2bf5eaeb0a 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -512,22 +512,20 @@ class MyArchitecture : public Architecture { unsigned bSize, bool* thunk) { - aMask.lowRegisterMask = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + aMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); *thunk = false; switch (op) { case lir::Negate: aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = (static_cast(1) << (rdx + 32)) - | (static_cast(1) << rax); + aMask.setLowHighRegisterMasks(1 << rax, 1 << rdx); break; case lir::Absolute: if (aSize <= TargetBytesPerWord) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = (static_cast(1) << rax); + aMask.setLowHighRegisterMasks(1 << rax, 0); } else { *thunk = true; } @@ -536,8 +534,7 @@ class MyArchitecture : public Architecture { case lir::FloatAbsolute: if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) - | FloatRegisterMask; + aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; } @@ -547,7 +544,7 @@ class MyArchitecture : public Architecture { // floatNegateRR does not support doubles if (useSSE(&c) and aSize == 4 and bSize == 4) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = FloatRegisterMask; + aMask.setLowHighRegisterMasks(FloatRegisterMask, 0); } else { *thunk = true; } @@ -557,8 +554,7 @@ class MyArchitecture : public Architecture { if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) - | FloatRegisterMask; + aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; } @@ -568,8 +564,7 @@ class MyArchitecture : public Architecture { if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) - | FloatRegisterMask; + aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; } @@ -583,8 +578,7 @@ class MyArchitecture : public Architecture { if (false and useSSE(&c) and bSize <= TargetBytesPerWord) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) - | FloatRegisterMask; + aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; } @@ -594,9 +588,7 @@ class MyArchitecture : public Architecture { if (useSSE(&c) and aSize <= TargetBytesPerWord) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - aMask.lowRegisterMask - = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + aMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } else { *thunk = true; } @@ -604,7 +596,7 @@ class MyArchitecture : public Architecture { case lir::Move: aMask.typeMask = ~0; - aMask.lowRegisterMask = ~static_cast(0); + aMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { @@ -612,13 +604,13 @@ class MyArchitecture : public Architecture { | (1 << lir::MemoryOperand); const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; + aMask.setLowHighRegisterMasks(mask, mask); } else if (aSize == 1 or bSize == 1) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); - aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; + aMask.setLowHighRegisterMasks(mask, mask); } } break; @@ -635,23 +627,24 @@ class MyArchitecture : public Architecture { OperandMask& bMask) { bMask.typeMask = ~0; - bMask.lowRegisterMask = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + bMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); switch (op) { case lir::Absolute: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = (static_cast(1) << rax); + bMask.setLowHighRegisterMasks(1 << rax, 0); break; case lir::FloatAbsolute: bMask.typeMask = (1 << lir::RegisterOperand); bMask.lowRegisterMask = aMask.lowRegisterMask; + bMask.highRegisterMask = aMask.highRegisterMask; break; case lir::Negate: bMask.typeMask = (1 << lir::RegisterOperand); bMask.lowRegisterMask = aMask.lowRegisterMask; + bMask.highRegisterMask = aMask.highRegisterMask; break; case lir::FloatNegate: @@ -659,8 +652,7 @@ class MyArchitecture : public Architecture { case lir::Float2Float: case lir::Int2Float: bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) - | FloatRegisterMask; + bMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); break; case lir::Float2Int: @@ -671,18 +663,14 @@ class MyArchitecture : public Architecture { if (aMask.typeMask & ((1 << lir::MemoryOperand) | 1 << lir::AddressOperand)) { bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) - << 32) | FloatRegisterMask; + bMask.setLowHighRegisterMasks(GeneralRegisterMask | FloatRegisterMask, GeneralRegisterMask); } else if (aMask.typeMask & (1 << lir::RegisterOperand)) { bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); if (aMask.lowRegisterMask & FloatRegisterMask) { - bMask.lowRegisterMask = FloatRegisterMask; + bMask.setLowHighRegisterMasks(FloatRegisterMask, 0); } else { - bMask.lowRegisterMask - = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + bMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } } else { bMask.typeMask = (1 << lir::RegisterOperand) @@ -691,12 +679,11 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { - bMask.lowRegisterMask = (static_cast(1) << (rdx + 32)) - | (static_cast(1) << rax); + bMask.setLowHighRegisterMasks(1 << rax, 1 << rdx); } else if (aSize == 1 or bSize == 1) { const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); - bMask.lowRegisterMask = (static_cast(mask) << 32) | mask; + bMask.setLowHighRegisterMasks(mask, mask); } } break; @@ -712,32 +699,26 @@ class MyArchitecture : public Architecture { const OperandMask& dstMask) { srcMask.typeMask = ~0; - srcMask.lowRegisterMask = ~static_cast(0); + srcMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); tmpMask.typeMask = 0; - tmpMask.lowRegisterMask = 0; + tmpMask.setLowHighRegisterMasks(0, 0); if (dstMask.typeMask & (1 << lir::MemoryOperand)) { // can't move directly from memory to memory srcMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); tmpMask.typeMask = 1 << lir::RegisterOperand; - tmpMask.lowRegisterMask - = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + tmpMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } else if (dstMask.typeMask & (1 << lir::RegisterOperand)) { if (size > TargetBytesPerWord) { // can't move directly from FPR to GPR or vice-versa for // values larger than the GPR size if (dstMask.lowRegisterMask & FloatRegisterMask) { - srcMask.lowRegisterMask - = FloatRegisterMask - | (static_cast(FloatRegisterMask) << 32); + srcMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); tmpMask.typeMask = 1 << lir::MemoryOperand; } else if (dstMask.lowRegisterMask & GeneralRegisterMask) { - srcMask.lowRegisterMask - = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + srcMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); tmpMask.typeMask = 1 << lir::MemoryOperand; } } @@ -749,9 +730,7 @@ class MyArchitecture : public Architecture { } else { tmpMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); - tmpMask.lowRegisterMask - = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + tmpMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } } } @@ -766,12 +745,10 @@ class MyArchitecture : public Architecture { bool* thunk) { aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); - aMask.lowRegisterMask = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + aMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); bMask.typeMask = (1 << lir::RegisterOperand); - bMask.lowRegisterMask = GeneralRegisterMask - | (static_cast(GeneralRegisterMask) << 32); + bMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); *thunk = false; @@ -785,10 +762,8 @@ class MyArchitecture : public Architecture { | (1 << lir::MemoryOperand); bMask.typeMask = (1 << lir::RegisterOperand); - const uint64_t mask = (static_cast(FloatRegisterMask) << 32) - | FloatRegisterMask; - aMask.lowRegisterMask = mask; - bMask.lowRegisterMask = mask; + aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); + bMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; } @@ -801,11 +776,11 @@ class MyArchitecture : public Architecture { case lir::Multiply: if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; - bMask.lowRegisterMask = (static_cast(1) << (rdx + 32)) | mask; + aMask.setLowHighRegisterMasks(mask, mask); + bMask.setLowHighRegisterMasks(mask, 1 << rdx); } else { - aMask.lowRegisterMask = GeneralRegisterMask; - bMask.lowRegisterMask = GeneralRegisterMask; + aMask.setLowHighRegisterMasks(GeneralRegisterMask, 0); + bMask.setLowHighRegisterMasks(GeneralRegisterMask, 0); } break; @@ -814,8 +789,8 @@ class MyArchitecture : public Architecture { *thunk = true; } else { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - bMask.lowRegisterMask = 1 << rax; + aMask.setLowHighRegisterMasks(GeneralRegisterMask & ~((1 << rax) | (1 << rdx)), 0); + bMask.setLowHighRegisterMasks(1 << rax, 0); } break; @@ -824,8 +799,8 @@ class MyArchitecture : public Architecture { *thunk = true; } else { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - bMask.lowRegisterMask = 1 << rax; + aMask.setLowHighRegisterMasks(GeneralRegisterMask & ~((1 << rax) | (1 << rdx)), 0); + bMask.setLowHighRegisterMasks(1 << rax, 0); } break; @@ -834,13 +809,12 @@ class MyArchitecture : public Architecture { case lir::UnsignedShiftRight: { if (TargetBytesPerWord == 4 and bSize == 8) { const uint32_t mask = GeneralRegisterMask & ~(1 << rcx); - aMask.lowRegisterMask = (static_cast(mask) << 32) | mask; - bMask.lowRegisterMask = (static_cast(mask) << 32) | mask; + aMask.setLowHighRegisterMasks(mask, mask); + bMask.setLowHighRegisterMasks(mask, mask); } else { - aMask.lowRegisterMask = (static_cast(GeneralRegisterMask) << 32) - | (static_cast(1) << rcx); + aMask.setLowHighRegisterMasks(static_cast(1) << rcx, GeneralRegisterMask); const uint32_t mask = GeneralRegisterMask & ~(1 << rcx); - bMask.lowRegisterMask = (static_cast(mask) << 32) | mask; + bMask.setLowHighRegisterMasks(mask, mask); } } break; @@ -856,10 +830,10 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (useSSE(&c)) { aMask.typeMask = (1 << lir::RegisterOperand); - aMask.lowRegisterMask = (static_cast(FloatRegisterMask) << 32) - | FloatRegisterMask; + aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); bMask.typeMask = aMask.typeMask; bMask.lowRegisterMask = aMask.lowRegisterMask; + bMask.highRegisterMask = aMask.highRegisterMask; } else { *thunk = true; } @@ -880,10 +854,11 @@ class MyArchitecture : public Architecture { { if (isBranch(op)) { cMask.typeMask = (1 << lir::ConstantOperand); - cMask.lowRegisterMask = 0; + cMask.setLowHighRegisterMasks(0, 0); } else { cMask.typeMask = (1 << lir::RegisterOperand); cMask.lowRegisterMask = bMask.lowRegisterMask; + cMask.highRegisterMask = bMask.highRegisterMask; } } From f187361889512a574f059e2d2e0d2ba76e57b63c Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 4 Dec 2014 15:18:54 -0700 Subject: [PATCH 08/70] rename RegisterMask to BoundedRegisterMask --- include/avian/codegen/registers.h | 14 +++++++------- src/codegen/registers.cpp | 4 ++-- unittest/codegen/registers-test.cpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index f152084605..b5f58c3111 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -16,7 +16,7 @@ namespace avian { namespace codegen { -class RegisterMask { +class BoundedRegisterMask { public: uint32_t mask; uint8_t start; @@ -25,7 +25,7 @@ class RegisterMask { static unsigned maskStart(uint32_t mask); static unsigned maskLimit(uint32_t mask); - inline RegisterMask(uint32_t mask) + inline BoundedRegisterMask(uint32_t mask) : mask(mask), start(maskStart(mask)), limit(maskLimit(mask)) { } @@ -33,9 +33,9 @@ class RegisterMask { class RegisterFile { public: - RegisterMask allRegisters; - RegisterMask generalRegisters; - RegisterMask floatRegisters; + BoundedRegisterMask allRegisters; + BoundedRegisterMask generalRegisters; + BoundedRegisterMask floatRegisters; inline RegisterFile(uint32_t generalRegisterMask, uint32_t floatRegisterMask) : allRegisters(generalRegisterMask | floatRegisterMask), @@ -48,9 +48,9 @@ class RegisterFile { class RegisterIterator { public: int index; - const RegisterMask& mask; + const BoundedRegisterMask& mask; - inline RegisterIterator(const RegisterMask& mask) + inline RegisterIterator(const BoundedRegisterMask& mask) : index(mask.start), mask(mask) { } diff --git a/src/codegen/registers.cpp b/src/codegen/registers.cpp index 0f13f56244..0404670f37 100644 --- a/src/codegen/registers.cpp +++ b/src/codegen/registers.cpp @@ -13,7 +13,7 @@ namespace avian { namespace codegen { -unsigned RegisterMask::maskStart(uint32_t mask) +unsigned BoundedRegisterMask::maskStart(uint32_t mask) { for (int i = 0; i <= 31; ++i) { if (mask & (1 << i)) @@ -22,7 +22,7 @@ unsigned RegisterMask::maskStart(uint32_t mask) return 32; } -unsigned RegisterMask::maskLimit(uint32_t mask) +unsigned BoundedRegisterMask::maskLimit(uint32_t mask) { for (int i = 31; i >= 0; --i) { if (mask & (1 << i)) diff --git a/unittest/codegen/registers-test.cpp b/unittest/codegen/registers-test.cpp index f565e813d7..392fc8e26e 100644 --- a/unittest/codegen/registers-test.cpp +++ b/unittest/codegen/registers-test.cpp @@ -19,7 +19,7 @@ using namespace vm; TEST(RegisterIterator) { - RegisterMask regs(0x55); + BoundedRegisterMask regs(0x55); assertEqual(0, regs.start); assertEqual(7, regs.limit); From a509575a86b216434b1b3e50053ed07e43d6cd75 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 4 Dec 2014 15:21:09 -0700 Subject: [PATCH 09/70] remove unused arm utilities / constants --- src/codegen/target/arm/assembler.cpp | 5 ----- src/codegen/target/arm/registers.h | 4 ---- 2 files changed, 9 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 8932c7ec83..84e7d8d3cc 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -52,11 +52,6 @@ bool vfpSupported() } } // namespace isa -inline unsigned lo8(int64_t i) -{ - return (unsigned)(i & MASK_LO8); -} - const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0); const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK); diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index ed639acac6..4cd7fb9da4 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -19,7 +19,6 @@ namespace codegen { namespace arm { const uint64_t MASK_LO32 = 0xffffffff; -const unsigned MASK_LO16 = 0xffff; const unsigned MASK_LO8 = 0xff; const int N_GPRS = 16; @@ -27,9 +26,6 @@ const int N_FPRS = 16; const uint32_t GPR_MASK = 0xffff; const uint32_t FPR_MASK = 0xffff0000; -const uint64_t GPR_MASK64 = GPR_MASK | (uint64_t)GPR_MASK << 32; -const uint64_t FPR_MASK64 = FPR_MASK | (uint64_t)FPR_MASK << 32; - inline bool isFpr(lir::Register* reg) { return reg->low >= N_GPRS; From 76197e1f1d1b979a3b98b9e39081cfc4f08c00e9 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 4 Dec 2014 15:26:47 -0700 Subject: [PATCH 10/70] typedef RegisterMask --- include/avian/codegen/architecture.h | 15 ++++++++------- include/avian/codegen/assembler.h | 3 ++- include/avian/codegen/registers.h | 12 +++++++----- src/codegen/compiler.cpp | 2 +- src/codegen/compiler/event.cpp | 2 +- src/codegen/compiler/regalloc.cpp | 14 +++++++------- src/codegen/compiler/regalloc.h | 6 +++--- src/codegen/compiler/site.cpp | 8 ++++---- src/codegen/compiler/site.h | 12 ++++++------ src/codegen/registers.cpp | 4 ++-- src/codegen/target/arm/registers.h | 4 ++-- src/codegen/target/x86/operations.cpp | 2 +- 12 files changed, 44 insertions(+), 40 deletions(-) diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index e4fa825af3..b43582cfe4 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -12,6 +12,7 @@ #define AVIAN_CODEGEN_ARCHITECTURE_H #include "ir.h" +#include "registers.h" namespace vm { class Zone; @@ -32,12 +33,12 @@ class RegisterFile; class OperandMask { public: uint8_t typeMask; - uint64_t lowRegisterMask; - uint64_t highRegisterMask; + RegisterMask lowRegisterMask; + RegisterMask highRegisterMask; OperandMask(uint8_t typeMask, - uint64_t lowRegisterMask, - uint64_t highRegisterMask) + RegisterMask lowRegisterMask, + RegisterMask highRegisterMask) : typeMask(typeMask), lowRegisterMask(lowRegisterMask), highRegisterMask(highRegisterMask) @@ -46,18 +47,18 @@ class OperandMask { // TEMPORARY! OperandMask(uint8_t typeMask, - uint64_t registerMask) + RegisterMask registerMask) : typeMask(typeMask), lowRegisterMask(registerMask), highRegisterMask(registerMask >> 32) { } - OperandMask() : typeMask(~0), lowRegisterMask(~static_cast(0)), highRegisterMask(~static_cast(0)) + OperandMask() : typeMask(~0), lowRegisterMask(~static_cast(0)), highRegisterMask(~static_cast(0)) { } - void setLowHighRegisterMasks(uint64_t lowRegisterMask, uint64_t highRegisterMask) { + void setLowHighRegisterMasks(RegisterMask lowRegisterMask, RegisterMask highRegisterMask) { this->lowRegisterMask = lowRegisterMask | (highRegisterMask << 32); this->highRegisterMask = highRegisterMask; } diff --git a/include/avian/codegen/assembler.h b/include/avian/codegen/assembler.h index 66e7ed53d6..a233fa82bf 100644 --- a/include/avian/codegen/assembler.h +++ b/include/avian/codegen/assembler.h @@ -15,6 +15,7 @@ #include "avian/zone.h" #include +#include #include namespace avian { @@ -52,7 +53,7 @@ class Assembler { public: class Client { public: - virtual int acquireTemporary(uint32_t mask = ~static_cast(0)) = 0; + virtual int acquireTemporary(RegisterMask mask = ~static_cast(0)) = 0; virtual void releaseTemporary(int r) = 0; virtual void save(int r) = 0; diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index b5f58c3111..0ddbf6e7dd 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -16,16 +16,18 @@ namespace avian { namespace codegen { +typedef uint64_t RegisterMask; + class BoundedRegisterMask { public: - uint32_t mask; + RegisterMask mask; uint8_t start; uint8_t limit; - static unsigned maskStart(uint32_t mask); - static unsigned maskLimit(uint32_t mask); + static unsigned maskStart(RegisterMask mask); + static unsigned maskLimit(RegisterMask mask); - inline BoundedRegisterMask(uint32_t mask) + inline BoundedRegisterMask(RegisterMask mask) : mask(mask), start(maskStart(mask)), limit(maskLimit(mask)) { } @@ -37,7 +39,7 @@ class RegisterFile { BoundedRegisterMask generalRegisters; BoundedRegisterMask floatRegisters; - inline RegisterFile(uint32_t generalRegisterMask, uint32_t floatRegisterMask) + inline RegisterFile(RegisterMask generalRegisterMask, RegisterMask floatRegisterMask) : allRegisters(generalRegisterMask | floatRegisterMask), generalRegisters(generalRegisterMask), floatRegisters(floatRegisterMask) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index eabe367586..1f5a23f0fe 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -2210,7 +2210,7 @@ class Client : public Assembler::Client { { } - virtual int acquireTemporary(uint32_t mask) + virtual int acquireTemporary(RegisterMask mask) { unsigned cost; int r = pickRegisterTarget(c, 0, mask, &cost); diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 9668897547..d49ec49a2f 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -372,7 +372,7 @@ class CallEvent : public Event { ? arguments.count : 0) { - uint32_t registerMask = c->regFile->generalRegisters.mask; + RegisterMask registerMask = c->regFile->generalRegisters.mask; if (callingConvention == ir::CallingConvention::Native) { assertT(c, (flags & Compiler::TailJump) == 0); diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 6f716df770..52ff8f8da5 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -59,7 +59,7 @@ unsigned resourceCost(Context* c, bool pickRegisterTarget(Context* c, int i, Value* v, - uint32_t mask, + RegisterMask mask, int* target, unsigned* cost, CostCalculator* costCalculator) @@ -74,7 +74,7 @@ bool pickRegisterTarget(Context* c, SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), costCalculator) + Target::MinimumRegisterCost; - if ((static_cast(1) << i) == mask) { + if ((static_cast(1) << i) == mask) { *cost = myCost; return true; } else if (myCost < *cost) { @@ -87,7 +87,7 @@ bool pickRegisterTarget(Context* c, int pickRegisterTarget(Context* c, Value* v, - uint32_t mask, + RegisterMask mask, unsigned* cost, CostCalculator* costCalculator) { @@ -119,7 +119,7 @@ int pickRegisterTarget(Context* c, Target pickRegisterTarget(Context* c, Value* v, - uint32_t mask, + RegisterMask mask, CostCalculator* costCalculator) { unsigned cost; @@ -234,14 +234,14 @@ Target pickTarget(Context* c, Value* value = read->value; - uint32_t registerMask + RegisterMask registerMask = (isFloatValue(value) ? ~0 : c->regFile->generalRegisters.mask); SiteMask mask(~0, registerMask, AnyFrameIndex); read->intersect(&mask); if (isFloatValue(value)) { - uint32_t floatMask = mask.registerMask & c->regFile->floatRegisters.mask; + RegisterMask floatMask = mask.registerMask & c->regFile->floatRegisters.mask; if (floatMask) { mask.registerMask = floatMask; } @@ -273,7 +273,7 @@ Target pickTarget(Context* c, if (intersectRead) { if (best.cost == Target::Impossible) { fprintf(stderr, - "mask type %d reg %d frame %d\n", + "mask type %d reg %" LLD " frame %d\n", mask.typeMask, mask.registerMask, mask.frameIndex); diff --git a/src/codegen/compiler/regalloc.h b/src/codegen/compiler/regalloc.h index 3c87b20c00..6aa782ab04 100644 --- a/src/codegen/compiler/regalloc.h +++ b/src/codegen/compiler/regalloc.h @@ -79,20 +79,20 @@ unsigned resourceCost(Context* c, bool pickRegisterTarget(Context* c, int i, Value* v, - uint32_t mask, + RegisterMask mask, int* target, unsigned* cost, CostCalculator* costCalculator = 0); int pickRegisterTarget(Context* c, Value* v, - uint32_t mask, + RegisterMask mask, unsigned* cost, CostCalculator* costCalculator = 0); Target pickRegisterTarget(Context* c, Value* v, - uint32_t mask, + RegisterMask mask, CostCalculator* costCalculator = 0); unsigned frameCost(Context* c, diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index ea762a851f..f5dd0e0ad9 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -217,7 +217,7 @@ Site* addressSite(Context* c, Promise* address) return new (c->zone) AddressSite(address); } -RegisterSite::RegisterSite(uint32_t mask, int number) +RegisterSite::RegisterSite(RegisterMask mask, int number) : mask_(mask), number(number) { } @@ -281,7 +281,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) assertT(c, number != lir::NoRegister); return number == rs->number; } else { - uint32_t mask = c->regFile->generalRegisters.mask; + RegisterMask mask = c->regFile->generalRegisters.mask; return ((1 << number) & mask) and ((1 << rs->number) & mask); } } @@ -354,7 +354,7 @@ void RegisterSite::asAssemblerOperand(Context* c UNUSED, Site* RegisterSite::copy(Context* c) { - uint32_t mask; + RegisterMask mask; if (number != lir::NoRegister) { mask = 1 << number; @@ -429,7 +429,7 @@ Site* registerSite(Context* c, int number) return new (c->zone) RegisterSite(1 << number, number); } -Site* freeRegisterSite(Context* c, uint32_t mask) +Site* freeRegisterSite(Context* c, RegisterMask mask) { return new (c->zone) RegisterSite(mask, lir::NoRegister); } diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 5c5e9daa35..a01a4f35e0 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -34,8 +34,8 @@ class SiteMask { { } - SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex) - : typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex) + SiteMask(uint8_t typeMask, RegisterMask registerMask, int frameIndex) + : typeMask(typeMask), registerMask(/*TODO: REMOVE CAST!!! */(uint32_t)registerMask), frameIndex(frameIndex) { } @@ -57,7 +57,7 @@ class SiteMask { } uint8_t typeMask; - uint32_t registerMask; + RegisterMask registerMask; int frameIndex; }; @@ -251,7 +251,7 @@ Site* addressSite(Context* c, Promise* address); class RegisterSite : public Site { public: - RegisterSite(uint32_t mask, int number); + RegisterSite(RegisterMask mask, int number); virtual unsigned toString(Context*, char* buffer, unsigned bufferSize); @@ -295,12 +295,12 @@ class RegisterSite : public Site { virtual unsigned registerMask(Context* c UNUSED); - uint32_t mask_; + RegisterMask mask_; int number; }; Site* registerSite(Context* c, int number); -Site* freeRegisterSite(Context* c, uint32_t mask); +Site* freeRegisterSite(Context* c, RegisterMask mask); class MemorySite : public Site { public: diff --git a/src/codegen/registers.cpp b/src/codegen/registers.cpp index 0404670f37..b2b6c9f607 100644 --- a/src/codegen/registers.cpp +++ b/src/codegen/registers.cpp @@ -13,7 +13,7 @@ namespace avian { namespace codegen { -unsigned BoundedRegisterMask::maskStart(uint32_t mask) +unsigned BoundedRegisterMask::maskStart(RegisterMask mask) { for (int i = 0; i <= 31; ++i) { if (mask & (1 << i)) @@ -22,7 +22,7 @@ unsigned BoundedRegisterMask::maskStart(uint32_t mask) return 32; } -unsigned BoundedRegisterMask::maskLimit(uint32_t mask) +unsigned BoundedRegisterMask::maskLimit(RegisterMask mask) { for (int i = 31; i >= 0; --i) { if (mask & (1 << i)) diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index 4cd7fb9da4..c47f2ae8c5 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -23,8 +23,8 @@ const unsigned MASK_LO8 = 0xff; const int N_GPRS = 16; const int N_FPRS = 16; -const uint32_t GPR_MASK = 0xffff; -const uint32_t FPR_MASK = 0xffff0000; +const RegisterMask GPR_MASK = 0xffff; +const RegisterMask FPR_MASK = 0xffff0000; inline bool isFpr(lir::Register* reg) { diff --git a/src/codegen/target/x86/operations.cpp b/src/codegen/target/x86/operations.cpp index 0301cda1eb..863d1cf5bf 100644 --- a/src/codegen/target/x86/operations.cpp +++ b/src/codegen/target/x86/operations.cpp @@ -1274,7 +1274,7 @@ void multiplyCR(Context* c, assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { - const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); + const RegisterMask mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); lir::Register tmp(c->client->acquireTemporary(mask), c->client->acquireTemporary(mask)); From 45cc85829a199dbf418ff706a2a53df3ffbd2700 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 4 Dec 2014 16:32:52 -0700 Subject: [PATCH 11/70] remove old 32-bit registerMask stuff --- include/avian/codegen/architecture.h | 11 +---------- src/codegen/compiler.cpp | 4 ++-- src/codegen/compiler/event.cpp | 26 ++++++++++---------------- src/codegen/compiler/site.h | 2 +- 4 files changed, 14 insertions(+), 29 deletions(-) diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index b43582cfe4..756a67012c 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -45,21 +45,12 @@ class OperandMask { { } - // TEMPORARY! - OperandMask(uint8_t typeMask, - RegisterMask registerMask) - : typeMask(typeMask), - lowRegisterMask(registerMask), - highRegisterMask(registerMask >> 32) - { - } - OperandMask() : typeMask(~0), lowRegisterMask(~static_cast(0)), highRegisterMask(~static_cast(0)) { } void setLowHighRegisterMasks(RegisterMask lowRegisterMask, RegisterMask highRegisterMask) { - this->lowRegisterMask = lowRegisterMask | (highRegisterMask << 32); + this->lowRegisterMask = lowRegisterMask; this->highRegisterMask = highRegisterMask; } }; diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 1f5a23f0fe..d4f05b4f8e 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -342,7 +342,7 @@ Site* maybeMove(Context* c, OperandMask src; OperandMask tmp; c->arch->planMove( - size, src, tmp, OperandMask(dstMask.typeMask, dstMask.registerMask)); + size, src, tmp, OperandMask(dstMask.typeMask, dstMask.registerMask, 0)); SiteMask srcMask = SiteMask::lowPart(src); for (SiteIterator it(c, value, true, includeNextWord); it.hasMore();) { @@ -369,7 +369,7 @@ Site* maybeMove(Context* c, size, src, tmp, - OperandMask(1 << dstSite->type(c), dstSite->registerMask(c))); + OperandMask(1 << dstSite->type(c), dstSite->registerMask(c), 0)); SiteMask srcMask = SiteMask::lowPart(src); unsigned cost = 0xFFFFFFFF; diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index d49ec49a2f..e2312db18f 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -784,8 +784,8 @@ class MoveEvent : public Event { srcSelectSize, OperandMask( 1 << srcValue->source->type(c), - (static_cast(srcValue->nextWord->source->registerMask(c)) - << 32) | static_cast(srcValue->source->registerMask(c))), + srcValue->source->registerMask(c), + srcValue->nextWord->source->registerMask(c)), dstSize, dst); @@ -1127,17 +1127,13 @@ class CombineEvent : public Event { firstValue->type.size(c->targetInfo), OperandMask( 1 << firstValue->source->type(c), - (static_cast( - firstValue->nextWord->source->registerMask(c)) - << 32) - | static_cast(firstValue->source->registerMask(c))), + firstValue->source->registerMask(c), + firstValue->nextWord->source->registerMask(c)), secondValue->type.size(c->targetInfo), OperandMask( 1 << secondValue->source->type(c), - (static_cast( - secondValue->nextWord->source->registerMask(c)) - << 32) - | static_cast(secondValue->source->registerMask(c))), + secondValue->source->registerMask(c), + secondValue->nextWord->source->registerMask(c)), resultValue->type.size(c->targetInfo), cMask); @@ -1319,10 +1315,8 @@ class TranslateEvent : public Event { firstValue->type.size(c->targetInfo), OperandMask( 1 << firstValue->source->type(c), - (static_cast( - firstValue->nextWord->source->registerMask(c)) - << 32) - | static_cast(firstValue->source->registerMask(c))), + firstValue->source->registerMask(c), + firstValue->nextWord->source->registerMask(c)), resultValue->type.size(c->targetInfo), bMask); @@ -1718,9 +1712,9 @@ class BranchEvent : public Event { OperandMask dstMask; c->arch->planDestination(op, firstValue->type.size(c->targetInfo), - OperandMask(0, 0), + OperandMask(0, 0, 0), firstValue->type.size(c->targetInfo), - OperandMask(0, 0), + OperandMask(0, 0, 0), c->targetInfo.pointerSize, dstMask); diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index a01a4f35e0..6d549c116e 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -35,7 +35,7 @@ class SiteMask { } SiteMask(uint8_t typeMask, RegisterMask registerMask, int frameIndex) - : typeMask(typeMask), registerMask(/*TODO: REMOVE CAST!!! */(uint32_t)registerMask), frameIndex(frameIndex) + : typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex) { } From 61e79d4f3b8d4443690fabbab3d28b298a1a5f47 Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 17:27:45 -0700 Subject: [PATCH 12/70] typdef Register --- include/avian/codegen/architecture.h | 2 +- include/avian/codegen/assembler.h | 6 +++--- include/avian/codegen/registers.h | 3 ++- src/codegen/compiler.cpp | 8 ++++---- src/codegen/compiler/event.cpp | 2 +- src/codegen/compiler/regalloc.cpp | 16 ++++++++-------- src/codegen/compiler/regalloc.h | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index 756a67012c..eabe7542dd 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -85,7 +85,7 @@ class Architecture { virtual bool argumentAlignment() = 0; virtual bool argumentRegisterAlignment() = 0; virtual unsigned argumentRegisterCount() = 0; - virtual int argumentRegister(unsigned index) = 0; + virtual Register argumentRegister(unsigned index) = 0; virtual bool hasLinkRegister() = 0; diff --git a/include/avian/codegen/assembler.h b/include/avian/codegen/assembler.h index a233fa82bf..06179aa777 100644 --- a/include/avian/codegen/assembler.h +++ b/include/avian/codegen/assembler.h @@ -53,10 +53,10 @@ class Assembler { public: class Client { public: - virtual int acquireTemporary(RegisterMask mask = ~static_cast(0)) = 0; - virtual void releaseTemporary(int r) = 0; + virtual Register acquireTemporary(RegisterMask mask = ~static_cast(0)) = 0; + virtual void releaseTemporary(Register r) = 0; - virtual void save(int r) = 0; + virtual void save(Register r) = 0; }; class Block { diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 0ddbf6e7dd..19261f0f23 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -17,6 +17,7 @@ namespace avian { namespace codegen { typedef uint64_t RegisterMask; +typedef int Register; class BoundedRegisterMask { public: @@ -62,7 +63,7 @@ class RegisterIterator { return index < mask.limit; } - inline int next() + inline Register next() { int r = index; do { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index d4f05b4f8e..32047d52fc 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -2210,22 +2210,22 @@ class Client : public Assembler::Client { { } - virtual int acquireTemporary(RegisterMask mask) + virtual Register acquireTemporary(RegisterMask mask) { unsigned cost; - int r = pickRegisterTarget(c, 0, mask, &cost); + Register r = pickRegisterTarget(c, 0, mask, &cost); expect(c, cost < Target::Impossible); save(r); c->registerResources[r].increment(c); return r; } - virtual void releaseTemporary(int r) + virtual void releaseTemporary(Register r) { c->registerResources[r].decrement(c); } - virtual void save(int r) + virtual void save(Register r) { RegisterResource* reg = c->registerResources + r; diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index e2312db18f..789d470f44 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -396,7 +396,7 @@ class CallEvent : public Event { SiteMask targetMask; if (index + (c->arch->argumentRegisterAlignment() ? footprint : 1) <= c->arch->argumentRegisterCount()) { - int number = c->arch->argumentRegister(index); + Register number = c->arch->argumentRegister(index); if (DebugReads) { fprintf(stderr, "reg %d arg read %p\n", number, v); diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 52ff8f8da5..5f597537b8 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -57,10 +57,10 @@ unsigned resourceCost(Context* c, } bool pickRegisterTarget(Context* c, - int i, + Register i, Value* v, RegisterMask mask, - int* target, + Register* target, unsigned* cost, CostCalculator* costCalculator) { @@ -85,17 +85,17 @@ bool pickRegisterTarget(Context* c, return false; } -int pickRegisterTarget(Context* c, +Register pickRegisterTarget(Context* c, Value* v, RegisterMask mask, unsigned* cost, CostCalculator* costCalculator) { - int target = lir::NoRegister; + Register target = lir::NoRegister; *cost = Target::Impossible; if (mask & c->regFile->generalRegisters.mask) { - for (int i = c->regFile->generalRegisters.limit - 1; + for (Register i = c->regFile->generalRegisters.limit - 1; i >= c->regFile->generalRegisters.start; --i) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { @@ -105,8 +105,8 @@ int pickRegisterTarget(Context* c, } if (mask & c->regFile->floatRegisters.mask) { - for (int i = c->regFile->floatRegisters.start; - i < static_cast(c->regFile->floatRegisters.limit); + for (Register i = c->regFile->floatRegisters.start; + i < static_cast(c->regFile->floatRegisters.limit); ++i) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; @@ -123,7 +123,7 @@ Target pickRegisterTarget(Context* c, CostCalculator* costCalculator) { unsigned cost; - int number = pickRegisterTarget(c, v, mask, &cost, costCalculator); + Register number = pickRegisterTarget(c, v, mask, &cost, costCalculator); return Target(number, lir::RegisterOperand, cost); } diff --git a/src/codegen/compiler/regalloc.h b/src/codegen/compiler/regalloc.h index 6aa782ab04..e512e63183 100644 --- a/src/codegen/compiler/regalloc.h +++ b/src/codegen/compiler/regalloc.h @@ -55,7 +55,7 @@ class Target { { } - Target(int index, lir::OperandType type, unsigned cost) + Target(Register index, lir::OperandType type, unsigned cost) : index(index), type(type), cost(cost) { } From 87465e890bd66711158f7fd28633b9031372682b Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 17:46:06 -0700 Subject: [PATCH 13/70] typedef Register and RegisterMask in arm --- src/codegen/target/arm/operations.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/codegen/target/arm/operations.h b/src/codegen/target/arm/operations.h index 4c3f53cb56..af2c70fc46 100644 --- a/src/codegen/target/arm/operations.h +++ b/src/codegen/target/arm/operations.h @@ -25,17 +25,17 @@ class Context; // shortcut functions -inline int newTemp(Context* con) +inline Register newTemp(Context* con) { return con->client->acquireTemporary(GPR_MASK); } -inline int newTemp(Context* con, unsigned mask) +inline Register newTemp(Context* con, RegisterMask mask) { return con->client->acquireTemporary(mask); } -inline void freeTemp(Context* con, int r) +inline void freeTemp(Context* con, Register r) { con->client->releaseTemporary(r); } From 94761711c9cecc4f7590fe614fed8e4d9e3a08b7 Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 17:44:30 -0700 Subject: [PATCH 14/70] make RegisterMask a class --- include/avian/codegen/architecture.h | 2 +- include/avian/codegen/assembler.h | 2 +- include/avian/codegen/registers.h | 42 ++++++++++++++++++++++++++-- src/codegen/compiler/regalloc.cpp | 8 +++--- src/codegen/compiler/resource.cpp | 8 +++--- src/codegen/compiler/site.cpp | 20 ++++++------- src/codegen/registers.cpp | 6 ++-- unittest/codegen/assembler-test.cpp | 2 +- 8 files changed, 65 insertions(+), 25 deletions(-) diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index eabe7542dd..193311b876 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -45,7 +45,7 @@ class OperandMask { { } - OperandMask() : typeMask(~0), lowRegisterMask(~static_cast(0)), highRegisterMask(~static_cast(0)) + OperandMask() : typeMask(~0), lowRegisterMask(RegisterMask::Any), highRegisterMask(RegisterMask::Any) { } diff --git a/include/avian/codegen/assembler.h b/include/avian/codegen/assembler.h index 06179aa777..4331c11465 100644 --- a/include/avian/codegen/assembler.h +++ b/include/avian/codegen/assembler.h @@ -53,7 +53,7 @@ class Assembler { public: class Client { public: - virtual Register acquireTemporary(RegisterMask mask = ~static_cast(0)) = 0; + virtual Register acquireTemporary(RegisterMask mask = RegisterMask::Any) = 0; virtual void releaseTemporary(Register r) = 0; virtual void save(Register r) = 0; diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 19261f0f23..57406d9a91 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -16,9 +16,47 @@ namespace avian { namespace codegen { -typedef uint64_t RegisterMask; typedef int Register; +class RegisterMask { +private: + uint64_t mask; +public: + RegisterMask(uint64_t mask) : mask(mask) {} + RegisterMask() : mask(0) {} + + RegisterMask operator &(RegisterMask o) const { + return RegisterMask(mask & o.mask); + } + + RegisterMask operator &=(RegisterMask o) { + mask &= o.mask; + return *this; + } + + RegisterMask operator |(RegisterMask o) const { + return RegisterMask(mask | o.mask); + } + + bool contains(Register reg) const { + return (mask & (static_cast(1) << reg)) != 0; + } + + bool containsExactly(Register reg) const { + return mask == (mask & (static_cast(1) << reg)); + } + + explicit operator uint64_t() const { + return mask; + } + + explicit operator bool() const { + return mask != 0; + } + + static RegisterMask Any; +}; + class BoundedRegisterMask { public: RegisterMask mask; @@ -68,7 +106,7 @@ class RegisterIterator { int r = index; do { index++; - } while (index < mask.limit && !(mask.mask & (1 << index))); + } while (index < mask.limit && !(mask.mask.contains(index))); return r; } }; diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 5f597537b8..b75162405d 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -64,7 +64,7 @@ bool pickRegisterTarget(Context* c, unsigned* cost, CostCalculator* costCalculator) { - if ((1 << i) & mask) { + if (mask.contains(i)) { RegisterResource* r = c->registerResources + i; unsigned myCost = resourceCost( @@ -74,7 +74,7 @@ bool pickRegisterTarget(Context* c, SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), costCalculator) + Target::MinimumRegisterCost; - if ((static_cast(1) << i) == mask) { + if (mask.containsExactly(i)) { *cost = myCost; return true; } else if (myCost < *cost) { @@ -235,7 +235,7 @@ Target pickTarget(Context* c, Value* value = read->value; RegisterMask registerMask - = (isFloatValue(value) ? ~0 : c->regFile->generalRegisters.mask); + = (isFloatValue(value) ? RegisterMask::Any : c->regFile->generalRegisters.mask); SiteMask mask(~0, registerMask, AnyFrameIndex); read->intersect(&mask); @@ -275,7 +275,7 @@ Target pickTarget(Context* c, fprintf(stderr, "mask type %d reg %" LLD " frame %d\n", mask.typeMask, - mask.registerMask, + (uint64_t)mask.registerMask, mask.frameIndex); abort(c); } diff --git a/src/codegen/compiler/resource.cpp b/src/codegen/compiler/resource.cpp index f9a307c1dc..13f64abb8e 100644 --- a/src/codegen/compiler/resource.cpp +++ b/src/codegen/compiler/resource.cpp @@ -88,7 +88,7 @@ void RegisterResource::freeze(Context* c, Value* v) freezeResource(c, this, v); if (freezeCount == 1 - and ((1 << index(c)) & c->regFile->generalRegisters.mask)) { + and c->regFile->generalRegisters.mask.contains(index(c))) { decrementAvailableGeneralRegisterCount(c); } } @@ -100,7 +100,7 @@ void RegisterResource::thaw(Context* c, Value* v) thawResource(c, this, v); if (freezeCount == 0 - and ((1 << index(c)) & c->regFile->generalRegisters.mask)) { + and c->regFile->generalRegisters.mask.contains(index(c))) { incrementAvailableGeneralRegisterCount(c); } } @@ -130,7 +130,7 @@ void RegisterResource::increment(Context* c) ++this->referenceCount; if (this->referenceCount == 1 - and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) { + and c->regFile->generalRegisters.mask.contains(this->index(c))) { decrementAvailableGeneralRegisterCount(c); } } @@ -150,7 +150,7 @@ void RegisterResource::decrement(Context* c) --this->referenceCount; if (this->referenceCount == 0 - and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) { + and c->regFile->generalRegisters.mask.contains(this->index(c))) { incrementAvailableGeneralRegisterCount(c); } } diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index f5dd0e0ad9..1f83991a4a 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -238,7 +238,7 @@ unsigned RegisterSite::copyCost(Context* c, Site* s) if (s and (this == s or (s->type(c) == lir::RegisterOperand - and (static_cast(s)->mask_ & (1 << number))))) { + and (static_cast(s)->mask_.contains(number))))) { return 0; } else { return RegisterCopyCost; @@ -250,7 +250,7 @@ bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) assertT(c, number != lir::NoRegister); if ((mask.typeMask & (1 << lir::RegisterOperand))) { - return ((static_cast(1) << number) & mask.registerMask); + return mask.registerMask.contains(number); } else { return false; } @@ -261,7 +261,7 @@ bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) assertT(c, number != lir::NoRegister); if ((mask.typeMask & (1 << lir::RegisterOperand))) { - return ((static_cast(1) << number) == mask.registerMask); + return mask.registerMask.containsExactly(number); } else { return false; } @@ -282,7 +282,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) return number == rs->number; } else { RegisterMask mask = c->regFile->generalRegisters.mask; - return ((1 << number) & mask) and ((1 << rs->number) & mask); + return mask.contains(number) and mask.contains(rs->number); } } @@ -378,7 +378,7 @@ Site* RegisterSite::copyHigh(Context* c) Site* RegisterSite::makeNextWord(Context* c, unsigned) { assertT(c, number != lir::NoRegister); - assertT(c, ((1 << number) & c->regFile->generalRegisters.mask)); + assertT(c, c->regFile->generalRegisters.mask.contains(number)); return freeRegisterSite(c, c->regFile->generalRegisters.mask); } @@ -405,7 +405,7 @@ unsigned RegisterSite::registerSize(Context* c) { assertT(c, number != lir::NoRegister); - if ((1 << number) & c->regFile->floatRegisters.mask) { + if (c->regFile->floatRegisters.mask.contains(number)) { return c->arch->floatRegisterSize(); } else { return c->targetInfo.pointerSize; @@ -423,8 +423,8 @@ Site* registerSite(Context* c, int number) { assertT(c, number >= 0); assertT(c, - (1 << number) & (c->regFile->generalRegisters.mask - | c->regFile->floatRegisters.mask)); + (c->regFile->generalRegisters.mask + | c->regFile->floatRegisters.mask).contains(number)); return new (c->zone) RegisterSite(1 << number, number); } @@ -467,9 +467,9 @@ unsigned MemorySite::copyCost(Context* c, Site* s) bool MemorySite::conflicts(const SiteMask& mask) { return (mask.typeMask & (1 << lir::RegisterOperand)) != 0 - and (((1 << base) & mask.registerMask) == 0 + and (!mask.registerMask.contains(base) or (index != lir::NoRegister - and ((1 << index) & mask.registerMask) == 0)); + and !mask.registerMask.contains(index))); } bool MemorySite::match(Context* c, const SiteMask& mask) diff --git a/src/codegen/registers.cpp b/src/codegen/registers.cpp index b2b6c9f607..c4a0923b54 100644 --- a/src/codegen/registers.cpp +++ b/src/codegen/registers.cpp @@ -16,7 +16,7 @@ namespace codegen { unsigned BoundedRegisterMask::maskStart(RegisterMask mask) { for (int i = 0; i <= 31; ++i) { - if (mask & (1 << i)) + if (mask.contains(i)) return i; } return 32; @@ -25,11 +25,13 @@ unsigned BoundedRegisterMask::maskStart(RegisterMask mask) unsigned BoundedRegisterMask::maskLimit(RegisterMask mask) { for (int i = 31; i >= 0; --i) { - if (mask & (1 << i)) + if (mask.contains(i)) return i + 1; } return 0; } +RegisterMask RegisterMask::Any(~static_cast(0)); + } // namespace codegen } // namespace avian diff --git a/unittest/codegen/assembler-test.cpp b/unittest/codegen/assembler-test.cpp index bffbe6daf6..70be09554d 100644 --- a/unittest/codegen/assembler-test.cpp +++ b/unittest/codegen/assembler-test.cpp @@ -79,6 +79,6 @@ TEST(ArchitecturePlan) (lir::UnaryOperation)op, vm::TargetBytesPerWord, mask, &thunk); assertFalse(thunk); assertNotEqual(static_cast(0), mask.typeMask); - assertNotEqual(static_cast(0), mask.lowRegisterMask); + assertNotEqual(static_cast(0), (uint64_t)mask.lowRegisterMask); } } From 2939480a650b8df5cdbe6f6200452f87cd3071ab Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 18:33:10 -0700 Subject: [PATCH 15/70] begin renaming lir:: types --- include/avian/codegen/assembler.h | 4 +- include/avian/codegen/lir.h | 19 ++-- src/codegen/compiler.cpp | 40 +++---- src/codegen/compiler/event.cpp | 40 +++---- src/codegen/compiler/read.cpp | 2 +- src/codegen/compiler/regalloc.cpp | 16 +-- src/codegen/compiler/regalloc.h | 4 +- src/codegen/compiler/site.cpp | 46 ++++---- src/codegen/compiler/site.h | 20 ++-- src/codegen/target/arm/assembler.cpp | 64 +++++------ src/codegen/target/arm/context.h | 12 +-- src/codegen/target/arm/multimethod.cpp | 22 ++-- src/codegen/target/arm/multimethod.h | 10 +- src/codegen/target/multimethod.h | 4 +- src/codegen/target/x86/assembler.cpp | 142 ++++++++++++------------- src/codegen/target/x86/context.h | 8 +- src/codegen/target/x86/multimethod.cpp | 30 +++--- src/codegen/target/x86/multimethod.h | 12 +-- src/compile.cpp | 44 ++++---- 19 files changed, 270 insertions(+), 269 deletions(-) diff --git a/include/avian/codegen/assembler.h b/include/avian/codegen/assembler.h index 4331c11465..25707f4853 100644 --- a/include/avian/codegen/assembler.h +++ b/include/avian/codegen/assembler.h @@ -26,11 +26,11 @@ class Architecture; class OperandInfo { public: const unsigned size; - const lir::OperandType type; + const lir::Operand::Type type; lir::Operand* const operand; inline OperandInfo(unsigned size, - lir::OperandType type, + lir::Operand::Type type, lir::Operand* operand) : size(size), type(type), operand(operand) { diff --git a/include/avian/codegen/lir.h b/include/avian/codegen/lir.h index 251e31aadd..91b48fb96d 100644 --- a/include/avian/codegen/lir.h +++ b/include/avian/codegen/lir.h @@ -79,17 +79,8 @@ const unsigned NonBranchTernaryOperationCount = FloatMin + 1; const unsigned BranchOperationCount = JumpIfFloatGreaterOrEqualOrUnordered - FloatMin; -enum OperandType { - ConstantOperand, - AddressOperand, - RegisterOperand, - MemoryOperand -}; - enum ValueType { ValueGeneral, ValueFloat }; -const unsigned OperandTypeCount = MemoryOperand + 1; - const int NoRegister = -1; inline bool isBranch(lir::TernaryOperation op) @@ -128,6 +119,16 @@ inline bool isFloatUnaryOp(lir::BinaryOperation op) } class Operand { +public: + + enum class Type { + Constant, + Address, + RegisterPair, + Memory + }; + + const static unsigned TypeCount = (unsigned)Type::Memory + 1; }; class Constant : public Operand { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 32047d52fc..1e367497d5 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -256,7 +256,7 @@ Site* pickTargetSite(Context* c, expect(c, target.cost < Target::Impossible); - if (target.type == lir::MemoryOperand) { + if (target.type == lir::Operand::Type::Memory) { return frameSite(c, target.index); } else { return registerSite(c, target.index); @@ -369,7 +369,7 @@ Site* maybeMove(Context* c, size, src, tmp, - OperandMask(1 << dstSite->type(c), dstSite->registerMask(c), 0)); + OperandMask(1 << (unsigned)dstSite->type(c), dstSite->registerMask(c), 0)); SiteMask srcMask = SiteMask::lowPart(src); unsigned cost = 0xFFFFFFFF; @@ -514,14 +514,14 @@ void steal(Context* c, Resource* r, Value* thief) SiteMask generalRegisterMask(Context* c) { - return SiteMask(1 << lir::RegisterOperand, + return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, c->regFile->generalRegisters.mask, NoFrameIndex); } SiteMask generalRegisterOrConstantMask(Context* c) { - return SiteMask((1 << lir::RegisterOperand) | (1 << lir::ConstantOperand), + return SiteMask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant), c->regFile->generalRegisters.mask, NoFrameIndex); } @@ -616,11 +616,11 @@ bool isHome(Value* v, int frameIndex) bool acceptForResolve(Context* c, Site* s, Read* read, const SiteMask& mask) { if (acceptMatch(c, s, read, mask) and (not s->frozen(c))) { - if (s->type(c) == lir::RegisterOperand) { + if (s->type(c) == lir::Operand::Type::RegisterPair) { return c->availableGeneralRegisterCount > ResolveRegisterReserveCount; } else { assertT(c, - s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))); + s->match(c, SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, AnyFrameIndex))); return isHome(read->value, offsetToFrameIndex(c, static_cast(s)->offset)); @@ -698,7 +698,7 @@ void apply(Context* c, { assertT(c, s1Low->type(c) == s1High->type(c)); - lir::OperandType s1Type = s1Low->type(c); + lir::Operand::Type s1Type = s1Low->type(c); OperandUnion s1Union; asAssemblerOperand(c, s1Low, s1High, &s1Union); @@ -717,11 +717,11 @@ void apply(Context* c, assertT(c, s1Low->type(c) == s1High->type(c)); assertT(c, s2Low->type(c) == s2High->type(c)); - lir::OperandType s1Type = s1Low->type(c); + lir::Operand::Type s1Type = s1Low->type(c); OperandUnion s1Union; asAssemblerOperand(c, s1Low, s1High, &s1Union); - lir::OperandType s2Type = s2Low->type(c); + lir::Operand::Type s2Type = s2Low->type(c); OperandUnion s2Union; asAssemblerOperand(c, s2Low, s2High, &s2Union); @@ -746,15 +746,15 @@ void apply(Context* c, assertT(c, s2Low->type(c) == s2High->type(c)); assertT(c, s3Low->type(c) == s3High->type(c)); - lir::OperandType s1Type = s1Low->type(c); + lir::Operand::Type s1Type = s1Low->type(c); OperandUnion s1Union; asAssemblerOperand(c, s1Low, s1High, &s1Union); - lir::OperandType s2Type = s2Low->type(c); + lir::Operand::Type s2Type = s2Low->type(c); OperandUnion s2Union; asAssemblerOperand(c, s2Low, s2High, &s2Union); - lir::OperandType s3Type = s3Low->type(c); + lir::Operand::Type s3Type = s3Low->type(c); OperandUnion s3Union; asAssemblerOperand(c, s3Low, s3High, &s3Union); @@ -782,7 +782,7 @@ void saveLocals(Context* c, Event* e) e->addRead( c, local->value, - SiteMask(1 << lir::MemoryOperand, 0, compiler::frameIndex(c, li))); + SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, compiler::frameIndex(c, li))); } } } @@ -815,10 +815,10 @@ void maybeMove(Context* c, if (cost) { // todo: let c->arch->planMove decide this: - bool useTemporary = ((target->type(c) == lir::MemoryOperand - and srcValue->source->type(c) == lir::MemoryOperand) + bool useTemporary = ((target->type(c) == lir::Operand::Type::Memory + and srcValue->source->type(c) == lir::Operand::Type::Memory) or (srcSelectSize < dstSize - and target->type(c) != lir::RegisterOperand)); + and target->type(c) != lir::Operand::Type::RegisterPair)); srcValue->source->freeze(c, srcValue); @@ -827,7 +827,7 @@ void maybeMove(Context* c, srcValue->source->thaw(c, srcValue); bool addOffset = srcSize != srcSelectSize and c->arch->bigEndian() - and srcValue->source->type(c) == lir::MemoryOperand; + and srcValue->source->type(c) == lir::Operand::Type::Memory; if (addOffset) { static_cast(srcValue->source)->offset @@ -878,7 +878,7 @@ void maybeMove(Context* c, } assertT(c, thunk == 0); - assertT(c, dstMask.typeMask & src.typeMask & (1 << lir::RegisterOperand)); + assertT(c, dstMask.typeMask & src.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)); Site* tmpTarget = freeRegisterSite(c, dstMask.registerMask & src.lowRegisterMask); @@ -1635,7 +1635,7 @@ bool resolveSourceSites(Context* c, Read* r = live(c, v); if (r and sites[el.localIndex] == 0) { - SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), + SiteMask mask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory), c->regFile->generalRegisters.mask, AnyFrameIndex); @@ -1677,7 +1677,7 @@ void resolveTargetSites(Context* c, Read* r = live(c, v); if (r and sites[el.localIndex] == 0) { - SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), + SiteMask mask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory), c->regFile->generalRegisters.mask, AnyFrameIndex); diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 789d470f44..d5b6a67dcf 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -415,7 +415,7 @@ class CallEvent : public Event { fprintf(stderr, "stack %d arg read %p\n", frameIndex, v); } - targetMask = SiteMask(1 << lir::MemoryOperand, 0, frameIndex); + targetMask = SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex); } this->addRead(c, v, targetMask); @@ -512,7 +512,7 @@ class CallEvent : public Event { this->addRead(c, v, generalRegisterMask(c)); } else { this->addRead( - c, v, SiteMask(1 << lir::MemoryOperand, 0, frameIndex)); + c, v, SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex)); } } } @@ -544,7 +544,7 @@ class CallEvent : public Event { this->addRead(c, stack->value, - SiteMask(1 << lir::MemoryOperand, 0, logicalIndex)); + SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, logicalIndex)); } stack = stack->next; @@ -581,11 +581,11 @@ class CallEvent : public Event { assertT( c, returnAddressSurrogate == 0 - or returnAddressSurrogate->source->type(c) == lir::RegisterOperand); + or returnAddressSurrogate->source->type(c) == lir::Operand::Type::RegisterPair); assertT( c, framePointerSurrogate == 0 - or framePointerSurrogate->source->type(c) == lir::RegisterOperand); + or framePointerSurrogate->source->type(c) == lir::Operand::Type::RegisterPair); int ras; if (returnAddressSurrogate) { @@ -783,7 +783,7 @@ class MoveEvent : public Event { op, srcSelectSize, OperandMask( - 1 << srcValue->source->type(c), + 1 << (unsigned)srcValue->source->type(c), srcValue->source->registerMask(c), srcValue->nextWord->source->registerMask(c)), dstSize, @@ -866,7 +866,7 @@ class MoveEvent : public Event { assertT(c, srcSelectSize == c->targetInfo.pointerSize); if (dstValue->nextWord->target or live(c, dstValue->nextWord)) { - assertT(c, dstLowMask.typeMask & (1 << lir::RegisterOperand)); + assertT(c, dstLowMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)); Site* low = freeRegisterSite(c, dstLowMask.registerMask); @@ -897,7 +897,7 @@ class MoveEvent : public Event { srcValue->source->thaw(c, srcValue); - assertT(c, dstHighMask.typeMask & (1 << lir::RegisterOperand)); + assertT(c, dstHighMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)); Site* high = freeRegisterSite(c, dstHighMask.registerMask); @@ -1126,12 +1126,12 @@ class CombineEvent : public Event { op, firstValue->type.size(c->targetInfo), OperandMask( - 1 << firstValue->source->type(c), + 1 << (unsigned)firstValue->source->type(c), firstValue->source->registerMask(c), firstValue->nextWord->source->registerMask(c)), secondValue->type.size(c->targetInfo), OperandMask( - 1 << secondValue->source->type(c), + 1 << (unsigned)secondValue->source->type(c), secondValue->source->registerMask(c), secondValue->nextWord->source->registerMask(c)), resultValue->type.size(c->targetInfo), @@ -1314,7 +1314,7 @@ class TranslateEvent : public Event { op, firstValue->type.size(c->targetInfo), OperandMask( - 1 << firstValue->source->type(c), + 1 << (unsigned)firstValue->source->type(c), firstValue->source->registerMask(c), firstValue->nextWord->source->registerMask(c)), resultValue->type.size(c->targetInfo), @@ -1451,7 +1451,7 @@ ConstantSite* findConstantSite(Context* c, Value* v) { for (SiteIterator it(c, v); it.hasMore();) { Site* s = it.next(); - if (s->type(c) == lir::ConstantOperand) { + if (s->type(c) == lir::Operand::Type::Constant) { return static_cast(s); } } @@ -1461,7 +1461,7 @@ ConstantSite* findConstantSite(Context* c, Value* v) void moveIfConflict(Context* c, Value* v, MemorySite* s) { if (v->reads) { - SiteMask mask(1 << lir::RegisterOperand, ~0, AnyFrameIndex); + SiteMask mask(1 << (unsigned)lir::Operand::Type::RegisterPair, ~0, AnyFrameIndex); v->reads->intersect(&mask); if (s->conflicts(mask)) { maybeMove(c, v->reads, true, false); @@ -1509,13 +1509,13 @@ class MemoryEvent : public Event { displacement += (constant->value->value() * scale); scale = 1; } else { - assertT(c, index->source->type(c) == lir::RegisterOperand); + assertT(c, index->source->type(c) == lir::Operand::Type::RegisterPair); indexRegister = static_cast(index->source)->number; } } else { indexRegister = lir::NoRegister; } - assertT(c, base->source->type(c) == lir::RegisterOperand); + assertT(c, base->source->type(c) == lir::Operand::Type::RegisterPair); int baseRegister = static_cast(base->source)->number; popRead(c, this, base); @@ -1873,12 +1873,12 @@ void clean(Context* c, Value* v, unsigned popIndex) { for (SiteIterator it(c, v); it.hasMore();) { Site* s = it.next(); - if (not(s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex)) + if (not(s->match(c, SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, AnyFrameIndex)) and offsetToFrameIndex(c, static_cast(s)->offset) >= popIndex)) { if (false and s->match(c, - SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))) { + SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, AnyFrameIndex))) { char buffer[256]; s->toString(c, buffer, 256); fprintf(stderr, @@ -2010,7 +2010,7 @@ class BoundsCheckEvent : public Event { lir::Constant handlerConstant(resolvedPromise(c, handler)); a->apply(lir::Call, OperandInfo(c->targetInfo.pointerSize, - lir::ConstantOperand, + lir::Operand::Type::Constant, &handlerConstant)); } } else { @@ -2032,7 +2032,7 @@ class BoundsCheckEvent : public Event { } if (constant == 0 or constant->value->value() >= 0) { - assertT(c, object->source->type(c) == lir::RegisterOperand); + assertT(c, object->source->type(c) == lir::Operand::Type::RegisterPair); MemorySite length(static_cast(object->source)->number, lengthOffset, lir::NoRegister, @@ -2066,7 +2066,7 @@ class BoundsCheckEvent : public Event { lir::Constant handlerConstant(resolvedPromise(c, handler)); a->apply(lir::Call, OperandInfo(c->targetInfo.pointerSize, - lir::ConstantOperand, + lir::Operand::Type::Constant, &handlerConstant)); nextPromise->offset = a->offset(); diff --git a/src/codegen/compiler/read.cpp b/src/codegen/compiler/read.cpp index 0c7d09fd76..d9909ed343 100644 --- a/src/codegen/compiler/read.cpp +++ b/src/codegen/compiler/read.cpp @@ -205,7 +205,7 @@ Read* StubRead::next(Context*) SingleRead* read(Context* c, const SiteMask& mask, Value* successor) { assertT(c, - (mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0); + (mask.typeMask != 1 << (unsigned)lir::Operand::Type::Memory) or mask.frameIndex >= 0); return new (c->zone) SingleRead(mask, successor); } diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index b75162405d..0c60ae0d0d 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -71,7 +71,7 @@ bool pickRegisterTarget(Context* c, c, v, r, - SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), + SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << i, NoFrameIndex), costCalculator) + Target::MinimumRegisterCost; if (mask.containsExactly(i)) { @@ -124,7 +124,7 @@ Target pickRegisterTarget(Context* c, { unsigned cost; Register number = pickRegisterTarget(c, v, mask, &cost, costCalculator); - return Target(number, lir::RegisterOperand, cost); + return Target(number, lir::Operand::Type::RegisterPair, cost); } unsigned frameCost(Context* c, @@ -135,7 +135,7 @@ unsigned frameCost(Context* c, return resourceCost(c, v, c->frameResources + frameIndex, - SiteMask(1 << lir::MemoryOperand, 0, frameIndex), + SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex), costCalculator) + Target::MinimumFrameCost; } @@ -147,7 +147,7 @@ Target pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) do { if (p->home >= 0) { Target mine(p->home, - lir::MemoryOperand, + lir::Operand::Type::Memory, frameCost(c, v, p->home, costCalculator)); if (mine.cost == Target::MinimumFrameCost) { @@ -168,7 +168,7 @@ Target pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) unsigned count = totalFrameSize(c); for (unsigned i = 0; i < count; ++i) { - Target mine(i, lir::MemoryOperand, frameCost(c, v, i, costCalculator)); + Target mine(i, lir::Operand::Type::Memory, frameCost(c, v, i, costCalculator)); if (mine.cost == Target::MinimumFrameCost) { return mine; } else if (mine.cost < best.cost) { @@ -186,7 +186,7 @@ Target pickTarget(Context* c, Target best, CostCalculator* costCalculator) { - if (mask.typeMask & (1 << lir::RegisterOperand)) { + if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) { Target mine = pickRegisterTarget(c, value, mask.registerMask, costCalculator); @@ -198,10 +198,10 @@ Target pickTarget(Context* c, } } - if (mask.typeMask & (1 << lir::MemoryOperand)) { + if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { if (mask.frameIndex >= 0) { Target mine(mask.frameIndex, - lir::MemoryOperand, + lir::Operand::Type::Memory, frameCost(c, value, mask.frameIndex, costCalculator)); if (mine.cost == Target::MinimumFrameCost) { return mine; diff --git a/src/codegen/compiler/regalloc.h b/src/codegen/compiler/regalloc.h index e512e63183..0dab9d1e3d 100644 --- a/src/codegen/compiler/regalloc.h +++ b/src/codegen/compiler/regalloc.h @@ -55,13 +55,13 @@ class Target { { } - Target(Register index, lir::OperandType type, unsigned cost) + Target(Register index, lir::Operand::Type type, unsigned cost) : index(index), type(type), cost(cost) { } int16_t index; - lir::OperandType type; + lir::Operand::Type type; uint8_t cost; }; diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 1f83991a4a..99ce5fb154 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -152,7 +152,7 @@ class AddressSite : public Site { virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << lir::AddressOperand); + return mask.typeMask & (1 << (unsigned)lir::Operand::Type::Address); } virtual bool loneMatch(Context*, const SiteMask&) @@ -165,9 +165,9 @@ class AddressSite : public Site { abort(c); } - virtual lir::OperandType type(Context*) + virtual lir::Operand::Type type(Context*) { - return lir::AddressOperand; + return lir::Operand::Type::Address; } virtual void asAssemblerOperand(Context* c UNUSED, @@ -201,7 +201,7 @@ class AddressSite : public Site { virtual SiteMask mask(Context*) { - return SiteMask(1 << lir::AddressOperand, 0, NoFrameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::Address, 0, NoFrameIndex); } virtual SiteMask nextWordMask(Context* c, unsigned) @@ -237,7 +237,7 @@ unsigned RegisterSite::copyCost(Context* c, Site* s) assertT(c, number != lir::NoRegister); if (s and (this == s - or (s->type(c) == lir::RegisterOperand + or (s->type(c) == lir::Operand::Type::RegisterPair and (static_cast(s)->mask_.contains(number))))) { return 0; } else { @@ -249,7 +249,7 @@ bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) { assertT(c, number != lir::NoRegister); - if ((mask.typeMask & (1 << lir::RegisterOperand))) { + if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { return mask.registerMask.contains(number); } else { return false; @@ -260,7 +260,7 @@ bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) { assertT(c, number != lir::NoRegister); - if ((mask.typeMask & (1 << lir::RegisterOperand))) { + if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { return mask.registerMask.containsExactly(number); } else { return false; @@ -271,7 +271,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) { assertT(c, number != lir::NoRegister); - if (s->type(c) != lir::RegisterOperand) { + if (s->type(c) != lir::Operand::Type::RegisterPair) { return false; } @@ -290,7 +290,7 @@ void RegisterSite::acquire(Context* c, Value* v) { Target target; if (number != lir::NoRegister) { - target = Target(number, lir::RegisterOperand, 0); + target = Target(number, lir::Operand::Type::RegisterPair, 0); } else { target = pickRegisterTarget(c, v, mask_); expect(c, target.cost < Target::Impossible); @@ -330,9 +330,9 @@ bool RegisterSite::frozen(Context* c UNUSED) return c->registerResources[number].freezeCount != 0; } -lir::OperandType RegisterSite::type(Context*) +lir::Operand::Type RegisterSite::type(Context*) { - return lir::RegisterOperand; + return lir::Operand::Type::RegisterPair; } void RegisterSite::asAssemblerOperand(Context* c UNUSED, @@ -385,7 +385,7 @@ Site* RegisterSite::makeNextWord(Context* c, unsigned) SiteMask RegisterSite::mask(Context* c UNUSED) { - return SiteMask(1 << lir::RegisterOperand, mask_, NoFrameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, mask_, NoFrameIndex); } SiteMask RegisterSite::nextWordMask(Context* c, unsigned) @@ -393,9 +393,9 @@ SiteMask RegisterSite::nextWordMask(Context* c, unsigned) assertT(c, number != lir::NoRegister); if (registerSize(c) > c->targetInfo.pointerSize) { - return SiteMask(1 << lir::RegisterOperand, number, NoFrameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, number, NoFrameIndex); } else { - return SiteMask(1 << lir::RegisterOperand, + return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, c->regFile->generalRegisters.mask, NoFrameIndex); } @@ -453,7 +453,7 @@ unsigned MemorySite::copyCost(Context* c, Site* s) { assertT(c, acquired); - if (s and (this == s or (s->type(c) == lir::MemoryOperand + if (s and (this == s or (s->type(c) == lir::Operand::Type::Memory and static_cast(s)->base == base and static_cast(s)->offset == offset and static_cast(s)->index == index @@ -466,7 +466,7 @@ unsigned MemorySite::copyCost(Context* c, Site* s) bool MemorySite::conflicts(const SiteMask& mask) { - return (mask.typeMask & (1 << lir::RegisterOperand)) != 0 + return (mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) != 0 and (!mask.registerMask.contains(base) or (index != lir::NoRegister and !mask.registerMask.contains(index))); @@ -476,7 +476,7 @@ bool MemorySite::match(Context* c, const SiteMask& mask) { assertT(c, acquired); - if (mask.typeMask & (1 << lir::MemoryOperand)) { + if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { if (mask.frameIndex >= 0) { if (base == c->arch->stack()) { assertT(c, index == lir::NoRegister); @@ -497,7 +497,7 @@ bool MemorySite::loneMatch(Context* c, const SiteMask& mask) { assertT(c, acquired); - if (mask.typeMask & (1 << lir::MemoryOperand)) { + if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { if (base == c->arch->stack()) { assertT(c, index == lir::NoRegister); @@ -513,7 +513,7 @@ bool MemorySite::loneMatch(Context* c, const SiteMask& mask) bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) { - if (s->type(c) == lir::MemoryOperand) { + if (s->type(c) == lir::Operand::Type::Memory) { MemorySite* ms = static_cast(s); return ms->base == this->base and ((index == 1 @@ -596,9 +596,9 @@ bool MemorySite::frozen(Context* c) and c->frameResources[offsetToFrameIndex(c, offset)].freezeCount != 0; } -lir::OperandType MemorySite::type(Context*) +lir::Operand::Type MemorySite::type(Context*) { - return lir::MemoryOperand; + return lir::Operand::Type::Memory; } void MemorySite::asAssemblerOperand(Context* c UNUSED, @@ -657,7 +657,7 @@ Site* MemorySite::makeNextWord(Context* c, unsigned index) SiteMask MemorySite::mask(Context* c) { - return SiteMask(1 << lir::MemoryOperand, + return SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, (base == c->arch->stack()) ? static_cast(offsetToFrameIndex(c, offset)) @@ -674,7 +674,7 @@ SiteMask MemorySite::nextWordMask(Context* c, unsigned index) } else { frameIndex = NoFrameIndex; } - return SiteMask(1 << lir::MemoryOperand, 0, frameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex); } bool MemorySite::isVolatile(Context* c) diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 6d549c116e..6344936e0c 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -43,7 +43,7 @@ class SiteMask { static SiteMask fixedRegisterMask(int number) { - return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << number, NoFrameIndex); } static SiteMask lowPart(const OperandMask& mask) @@ -103,7 +103,7 @@ class Site { return false; } - virtual lir::OperandType type(Context*) = 0; + virtual lir::Operand::Type type(Context*) = 0; virtual void asAssemblerOperand(Context*, Site*, lir::Operand*) = 0; @@ -187,7 +187,7 @@ class ConstantSite : public Site { virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << lir::ConstantOperand); + return mask.typeMask & (1 << (unsigned)lir::Operand::Type::Constant); } virtual bool loneMatch(Context*, const SiteMask&) @@ -197,12 +197,12 @@ class ConstantSite : public Site { virtual bool matchNextWord(Context* c, Site* s, unsigned) { - return s->type(c) == lir::ConstantOperand; + return s->type(c) == lir::Operand::Type::Constant; } - virtual lir::OperandType type(Context*) + virtual lir::Operand::Type type(Context*) { - return lir::ConstantOperand; + return lir::Operand::Type::Constant; } virtual void asAssemblerOperand(Context* c, Site* high, lir::Operand* result) @@ -236,12 +236,12 @@ class ConstantSite : public Site { virtual SiteMask mask(Context*) { - return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::Constant, 0, NoFrameIndex); } virtual SiteMask nextWordMask(Context*, unsigned) { - return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::Constant, 0, NoFrameIndex); } Promise* value; @@ -273,7 +273,7 @@ class RegisterSite : public Site { virtual bool frozen(Context* c UNUSED); - virtual lir::OperandType type(Context*); + virtual lir::Operand::Type type(Context*); virtual void asAssemblerOperand(Context* c UNUSED, Site* high, @@ -328,7 +328,7 @@ class MemorySite : public Site { virtual bool frozen(Context* c); - virtual lir::OperandType type(Context*); + virtual lir::Operand::Type type(Context*); virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 84e7d8d3cc..c383aea819 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -396,7 +396,7 @@ class MyArchitecture : public Architecture { OperandMask& aMask, bool* thunk) { - aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant); aMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); *thunk = false; } @@ -413,7 +413,7 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Negate: - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; @@ -426,7 +426,7 @@ class MyArchitecture : public Architecture { case lir::FloatNegate: case lir::Float2Float: if (vfpSupported()) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); } else { *thunk = true; @@ -439,7 +439,7 @@ class MyArchitecture : public Architecture { // thunks or produce inline machine code which handles edge // cases properly. if (false && vfpSupported() && bSize == 4) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); } else { *thunk = true; @@ -448,7 +448,7 @@ class MyArchitecture : public Architecture { case lir::Int2Float: if (vfpSupported() && aSize == 4) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); } else { *thunk = true; @@ -466,12 +466,12 @@ class MyArchitecture : public Architecture { unsigned, OperandMask& bMask) { - bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory); bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); switch (op) { case lir::Negate: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; @@ -480,18 +480,18 @@ class MyArchitecture : public Architecture { case lir::FloatNegate: case lir::Float2Float: case lir::Int2Float: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); break; case lir::Float2Int: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; case lir::Move: - if (!(aMask.typeMask & 1 << lir::RegisterOperand)) { - bMask.typeMask = 1 << lir::RegisterOperand; + if (!(aMask.typeMask & 1 << (unsigned)lir::Operand::Type::RegisterPair)) { + bMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; } break; @@ -511,15 +511,15 @@ class MyArchitecture : public Architecture { tmpMask.typeMask = 0; tmpMask.setLowHighRegisterMasks(0, 0); - if (dstMask.typeMask & (1 << lir::MemoryOperand)) { + if (dstMask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { // can't move directly from memory or constant to memory - srcMask.typeMask = 1 << lir::RegisterOperand; - tmpMask.typeMask = 1 << lir::RegisterOperand; + srcMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; + tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; tmpMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); - } else if (vfpSupported() && dstMask.typeMask & 1 << lir::RegisterOperand + } else if (vfpSupported() && dstMask.typeMask & 1 << (unsigned)lir::Operand::Type::RegisterPair && dstMask.lowRegisterMask & FPR_MASK) { - srcMask.typeMask = tmpMask.typeMask = 1 << lir::RegisterOperand - | 1 << lir::MemoryOperand; + srcMask.typeMask = tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair + | 1 << (unsigned)lir::Operand::Type::Memory; tmpMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); } } @@ -532,10 +532,10 @@ class MyArchitecture : public Architecture { unsigned, bool* thunk) { - aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant); aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); *thunk = false; @@ -545,7 +545,7 @@ class MyArchitecture : public Architecture { case lir::ShiftRight: case lir::UnsignedShiftRight: if (bSize == 8) - aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); break; case lir::Add: @@ -553,7 +553,7 @@ class MyArchitecture : public Architecture { case lir::Or: case lir::Xor: case lir::Multiply: - aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); break; case lir::Divide: @@ -567,7 +567,7 @@ class MyArchitecture : public Architecture { case lir::FloatMultiply: case lir::FloatDivide: if (vfpSupported()) { - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); bMask = aMask; } else { @@ -586,7 +586,7 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatLessOrEqualOrUnordered: case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (vfpSupported()) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); bMask = aMask; } else { @@ -608,10 +608,10 @@ class MyArchitecture : public Architecture { OperandMask& cMask) { if (isBranch(op)) { - cMask.typeMask = (1 << lir::ConstantOperand); + cMask.typeMask = (1 << (unsigned)lir::Operand::Type::Constant); cMask.setLowHighRegisterMasks(0, 0); } else { - cMask.typeMask = (1 << lir::RegisterOperand); + cMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); cMask.lowRegisterMask = bMask.lowRegisterMask; cMask.highRegisterMask = bMask.highRegisterMask; } @@ -682,7 +682,7 @@ class MyAssembler : public Assembler { { struct Argument { unsigned size; - lir::OperandType type; + lir::Operand::Type type; lir::Operand* operand; }; RUNTIME_ARRAY(Argument, arguments, argumentCount); @@ -693,7 +693,7 @@ class MyAssembler : public Assembler { for (unsigned i = 0; i < argumentCount; ++i) { RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned); RUNTIME_ARRAY_BODY(arguments)[i].type - = static_cast(va_arg(a, int)); + = static_cast(va_arg(a, int)); RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*); footprint += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); @@ -713,7 +713,7 @@ class MyAssembler : public Assembler { RUNTIME_ARRAY_BODY(arguments)[i].operand), OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), - lir::RegisterOperand, + lir::Operand::Type::RegisterPair, &dst)); offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, @@ -727,7 +727,7 @@ class MyAssembler : public Assembler { RUNTIME_ARRAY_BODY(arguments)[i].operand), OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), - lir::MemoryOperand, + lir::Operand::Type::Memory, &dst)); offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, @@ -888,14 +888,14 @@ class MyAssembler : public Assembler { if (isBranch(op)) { assertT(&con, a.size == b.size); assertT(&con, c.size == TargetBytesPerWord); - assertT(&con, c.type == lir::ConstantOperand); + assertT(&con, c.type == lir::Operand::Type::Constant); arch_->con.branchOperations[branchIndex(&(arch_->con), a.type, b.type)]( &con, op, a.size, a.operand, b.operand, c.operand); } else { assertT(&con, b.size == c.size); - assertT(&con, b.type == lir::RegisterOperand); - assertT(&con, c.type == lir::RegisterOperand); + assertT(&con, b.type == lir::Operand::Type::RegisterPair); + assertT(&con, c.type == lir::Operand::Type::RegisterPair); arch_->con.ternaryOperations[index(&(arch_->con), op, a.type)]( &con, b.size, a.operand, b.operand, c.operand); diff --git a/src/codegen/target/arm/context.h b/src/codegen/target/arm/context.h index 45d937da9b..fde5a54a29 100644 --- a/src/codegen/target/arm/context.h +++ b/src/codegen/target/arm/context.h @@ -85,15 +85,15 @@ class ArchitectureContext { vm::System* s; OperationType operations[lir::OperationCount]; UnaryOperationType - unaryOperations[lir::UnaryOperationCount * lir::OperandTypeCount]; + unaryOperations[lir::UnaryOperationCount * lir::Operand::TypeCount]; BinaryOperationType binaryOperations[lir::BinaryOperationCount - * lir::OperandTypeCount - * lir::OperandTypeCount]; + * lir::Operand::TypeCount + * lir::Operand::TypeCount]; TernaryOperationType ternaryOperations[lir::NonBranchTernaryOperationCount - * lir::OperandTypeCount]; + * lir::Operand::TypeCount]; BranchOperationType branchOperations[lir::BranchOperationCount - * lir::OperandTypeCount - * lir::OperandTypeCount]; + * lir::Operand::TypeCount + * lir::Operand::TypeCount]; }; inline avian::util::Aborter* getAborter(Context* c) diff --git a/src/codegen/target/arm/multimethod.cpp b/src/codegen/target/arm/multimethod.cpp index 0ee2a642bc..c01c934e5b 100644 --- a/src/codegen/target/arm/multimethod.cpp +++ b/src/codegen/target/arm/multimethod.cpp @@ -22,16 +22,16 @@ using namespace util; unsigned index(ArchitectureContext*, lir::BinaryOperation operation, - lir::OperandType operand1, - lir::OperandType operand2) + lir::Operand::Type operand1, + lir::Operand::Type operand2) { return operation + (lir::BinaryOperationCount * operand1) - + (lir::BinaryOperationCount * lir::OperandTypeCount * operand2); + + (lir::BinaryOperationCount * lir::Operand::TypeCount * operand2); } unsigned index(ArchitectureContext* con UNUSED, lir::TernaryOperation operation, - lir::OperandType operand1) + lir::Operand::Type operand1) { assertT(con, not isBranch(operation)); @@ -39,18 +39,18 @@ unsigned index(ArchitectureContext* con UNUSED, } unsigned branchIndex(ArchitectureContext* con UNUSED, - lir::OperandType operand1, - lir::OperandType operand2) + lir::Operand::Type operand1, + lir::Operand::Type operand2) { - return operand1 + (lir::OperandTypeCount * operand2); + return operand1 + (lir::Operand::TypeCount * operand2); } void populateTables(ArchitectureContext* con) { - const lir::OperandType C = lir::ConstantOperand; - const lir::OperandType A = lir::AddressOperand; - const lir::OperandType R = lir::RegisterOperand; - const lir::OperandType M = lir::MemoryOperand; + const lir::Operand::Type C = lir::Operand::Type::Constant; + const lir::Operand::Type A = lir::Operand::Type::Address; + const lir::Operand::Type R = lir::Operand::Type::RegisterPair; + const lir::Operand::Type M = lir::Operand::Type::Memory; OperationType* zo = con->operations; UnaryOperationType* uo = con->unaryOperations; diff --git a/src/codegen/target/arm/multimethod.h b/src/codegen/target/arm/multimethod.h index 1949bf5486..f234385ee6 100644 --- a/src/codegen/target/arm/multimethod.h +++ b/src/codegen/target/arm/multimethod.h @@ -25,16 +25,16 @@ namespace arm { unsigned index(ArchitectureContext*, lir::BinaryOperation operation, - lir::OperandType operand1, - lir::OperandType operand2); + lir::Operand::Type operand1, + lir::Operand::Type operand2); unsigned index(ArchitectureContext* con UNUSED, lir::TernaryOperation operation, - lir::OperandType operand1); + lir::Operand::Type operand1); unsigned branchIndex(ArchitectureContext* con UNUSED, - lir::OperandType operand1, - lir::OperandType operand2); + lir::Operand::Type operand1, + lir::Operand::Type operand2); void populateTables(ArchitectureContext* con); diff --git a/src/codegen/target/multimethod.h b/src/codegen/target/multimethod.h index e5de2ca23c..965d16a402 100644 --- a/src/codegen/target/multimethod.h +++ b/src/codegen/target/multimethod.h @@ -17,9 +17,9 @@ namespace codegen { class Multimethod { public: inline static unsigned index(lir::UnaryOperation operation, - lir::OperandType operand) + lir::Operand::Type operand) { - return operation + (lir::UnaryOperationCount * operand); + return operation + (lir::UnaryOperationCount * (unsigned)operand); } }; diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index 2bf5eaeb0a..4049683651 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -501,8 +501,8 @@ class MyArchitecture : public Architecture { OperandMask& aMask, bool* thunk) { - aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand) - | (1 << lir::ConstantOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory) + | (1 << (unsigned)lir::Operand::Type::Constant); *thunk = false; } @@ -518,13 +518,13 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Negate: - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(1 << rax, 1 << rdx); break; case lir::Absolute: if (aSize <= TargetBytesPerWord) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(1 << rax, 0); } else { *thunk = true; @@ -533,7 +533,7 @@ class MyArchitecture : public Architecture { case lir::FloatAbsolute: if (useSSE(&c)) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -543,7 +543,7 @@ class MyArchitecture : public Architecture { case lir::FloatNegate: // floatNegateRR does not support doubles if (useSSE(&c) and aSize == 4 and bSize == 4) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FloatRegisterMask, 0); } else { *thunk = true; @@ -552,8 +552,8 @@ class MyArchitecture : public Architecture { case lir::FloatSquareRoot: if (useSSE(&c)) { - aMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -562,8 +562,8 @@ class MyArchitecture : public Architecture { case lir::Float2Float: if (useSSE(&c)) { - aMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -576,8 +576,8 @@ class MyArchitecture : public Architecture { // thunks or produce inline machine code which handles edge // cases properly. if (false and useSSE(&c) and bSize <= TargetBytesPerWord) { - aMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -586,8 +586,8 @@ class MyArchitecture : public Architecture { case lir::Int2Float: if (useSSE(&c) and aSize <= TargetBytesPerWord) { - aMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); aMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } else { *thunk = true; @@ -600,14 +600,14 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { - aMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); aMask.setLowHighRegisterMasks(mask, mask); } else if (aSize == 1 or bSize == 1) { - aMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); aMask.setLowHighRegisterMasks(mask, mask); @@ -631,18 +631,18 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Absolute: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(1 << rax, 0); break; case lir::FloatAbsolute: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.lowRegisterMask = aMask.lowRegisterMask; bMask.highRegisterMask = aMask.highRegisterMask; break; case lir::Negate: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.lowRegisterMask = aMask.lowRegisterMask; bMask.highRegisterMask = aMask.highRegisterMask; break; @@ -651,30 +651,30 @@ class MyArchitecture : public Architecture { case lir::FloatSquareRoot: case lir::Float2Float: case lir::Int2Float: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); break; case lir::Float2Int: - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); break; case lir::Move: if (aMask.typeMask - & ((1 << lir::MemoryOperand) | 1 << lir::AddressOperand)) { - bMask.typeMask = (1 << lir::RegisterOperand); + & ((1 << (unsigned)lir::Operand::Type::Memory) | 1 << (unsigned)lir::Operand::Type::Address)) { + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(GeneralRegisterMask | FloatRegisterMask, GeneralRegisterMask); - } else if (aMask.typeMask & (1 << lir::RegisterOperand)) { - bMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + } else if (aMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) { + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); if (aMask.lowRegisterMask & FloatRegisterMask) { bMask.setLowHighRegisterMasks(FloatRegisterMask, 0); } else { bMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } } else { - bMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); } if (TargetBytesPerWord == 4) { @@ -704,32 +704,32 @@ class MyArchitecture : public Architecture { tmpMask.typeMask = 0; tmpMask.setLowHighRegisterMasks(0, 0); - if (dstMask.typeMask & (1 << lir::MemoryOperand)) { + if (dstMask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { // can't move directly from memory to memory - srcMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::ConstantOperand); - tmpMask.typeMask = 1 << lir::RegisterOperand; + srcMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Constant); + tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; tmpMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); - } else if (dstMask.typeMask & (1 << lir::RegisterOperand)) { + } else if (dstMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) { if (size > TargetBytesPerWord) { // can't move directly from FPR to GPR or vice-versa for // values larger than the GPR size if (dstMask.lowRegisterMask & FloatRegisterMask) { srcMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); - tmpMask.typeMask = 1 << lir::MemoryOperand; + tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::Memory; } else if (dstMask.lowRegisterMask & GeneralRegisterMask) { srcMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); - tmpMask.typeMask = 1 << lir::MemoryOperand; + tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::Memory; } } if (dstMask.lowRegisterMask & FloatRegisterMask) { // can't move directly from constant to FPR - srcMask.typeMask &= ~(1 << lir::ConstantOperand); + srcMask.typeMask &= ~(1 << (unsigned)lir::Operand::Type::Constant); if (size > TargetBytesPerWord) { - tmpMask.typeMask = 1 << lir::MemoryOperand; + tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::Memory; } else { - tmpMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); + tmpMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); tmpMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } } @@ -744,10 +744,10 @@ class MyArchitecture : public Architecture { unsigned, bool* thunk) { - aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant); aMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); - bMask.typeMask = (1 << lir::RegisterOperand); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); bMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); *thunk = false; @@ -758,9 +758,9 @@ class MyArchitecture : public Architecture { case lir::FloatMultiply: case lir::FloatDivide: if (useSSE(&c)) { - aMask.typeMask = (1 << lir::RegisterOperand) - | (1 << lir::MemoryOperand); - bMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) + | (1 << (unsigned)lir::Operand::Type::Memory); + bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); bMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); @@ -788,7 +788,7 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(GeneralRegisterMask & ~((1 << rax) | (1 << rdx)), 0); bMask.setLowHighRegisterMasks(1 << rax, 0); } @@ -798,7 +798,7 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(GeneralRegisterMask & ~((1 << rax) | (1 << rdx)), 0); bMask.setLowHighRegisterMasks(1 << rax, 0); } @@ -829,7 +829,7 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatLessOrEqualOrUnordered: case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (useSSE(&c)) { - aMask.typeMask = (1 << lir::RegisterOperand); + aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); bMask.typeMask = aMask.typeMask; bMask.lowRegisterMask = aMask.lowRegisterMask; @@ -853,10 +853,10 @@ class MyArchitecture : public Architecture { OperandMask& cMask) { if (isBranch(op)) { - cMask.typeMask = (1 << lir::ConstantOperand); + cMask.typeMask = (1 << (unsigned)lir::Operand::Type::Constant); cMask.setLowHighRegisterMasks(0, 0); } else { - cMask.typeMask = (1 << lir::RegisterOperand); + cMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); cMask.lowRegisterMask = bMask.lowRegisterMask; cMask.highRegisterMask = bMask.highRegisterMask; } @@ -918,8 +918,8 @@ class MyAssembler : public Assembler { lir::Register stack(rsp); lir::Memory stackDst(rbx, stackOffset); apply(lir::Move, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), - OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &stackDst)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Memory, &stackDst)); } virtual void pushFrame(unsigned argumentCount, ...) @@ -927,7 +927,7 @@ class MyAssembler : public Assembler { // TODO: Argument should be replaced by OperandInfo... struct Argument { unsigned size; - lir::OperandType type; + lir::Operand::Type type; lir::Operand* operand; }; RUNTIME_ARRAY(Argument, arguments, argumentCount); @@ -937,7 +937,7 @@ class MyAssembler : public Assembler { for (unsigned i = 0; i < argumentCount; ++i) { RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned); RUNTIME_ARRAY_BODY(arguments)[i].type - = static_cast(va_arg(a, int)); + = static_cast(va_arg(a, int)); RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*); footprint += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); @@ -956,7 +956,7 @@ class MyAssembler : public Assembler { RUNTIME_ARRAY_BODY(arguments)[i].operand), OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), - lir::RegisterOperand, + lir::Operand::Type::RegisterPair, &dst)); } else { lir::Memory dst(rsp, offset * TargetBytesPerWord); @@ -966,7 +966,7 @@ class MyAssembler : public Assembler { RUNTIME_ARRAY_BODY(arguments)[i].operand), OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), - lir::MemoryOperand, + lir::Operand::Type::Memory, &dst)); offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); @@ -983,17 +983,17 @@ class MyAssembler : public Assembler { pushR(&c, TargetBytesPerWord, &base); apply(lir::Move, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &base)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &base)); } lir::Constant footprintConstant( resolvedPromise(&c, footprint * TargetBytesPerWord)); apply(lir::Subtract, OperandInfo( - TargetBytesPerWord, lir::ConstantOperand, &footprintConstant), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); + TargetBytesPerWord, lir::Operand::Type::Constant, &footprintConstant), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack)); } virtual void adjustFrame(unsigned difference) @@ -1003,9 +1003,9 @@ class MyAssembler : public Assembler { resolvedPromise(&c, difference * TargetBytesPerWord)); apply(lir::Subtract, OperandInfo( - TargetBytesPerWord, lir::ConstantOperand, &differenceConstant), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); + TargetBytesPerWord, lir::Operand::Type::Constant, &differenceConstant), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack)); } virtual void popFrame(unsigned frameFootprint) @@ -1014,8 +1014,8 @@ class MyAssembler : public Assembler { lir::Register base(rbp); lir::Register stack(rsp); apply(lir::Move, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &base), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &base), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack)); popR(&c, TargetBytesPerWord, &base); } else { @@ -1023,9 +1023,9 @@ class MyAssembler : public Assembler { lir::Constant footprint( resolvedPromise(&c, frameFootprint * TargetBytesPerWord)); apply(lir::Add, - OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &footprint), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Constant, &footprint), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack)); } } @@ -1157,7 +1157,7 @@ class MyAssembler : public Assembler { if (isBranch(op)) { assertT(&this->c, a.size == b.size); assertT(&this->c, c.size == TargetBytesPerWord); - assertT(&this->c, c.type == lir::ConstantOperand); + assertT(&this->c, c.type == lir::Operand::Type::Constant); arch_->c.branchOperations[branchIndex(&(arch_->c), a.type, b.type)]( &this->c, op, a.size, a.operand, b.operand, c.operand); diff --git a/src/codegen/target/x86/context.h b/src/codegen/target/x86/context.h index 93a6f1cc5b..89f877ce1a 100644 --- a/src/codegen/target/x86/context.h +++ b/src/codegen/target/x86/context.h @@ -68,13 +68,13 @@ class ArchitectureContext { bool useNativeFeatures; OperationType operations[lir::OperationCount]; UnaryOperationType - unaryOperations[lir::UnaryOperationCount * lir::OperandTypeCount]; + unaryOperations[lir::UnaryOperationCount * lir::Operand::TypeCount]; BinaryOperationType binaryOperations [(lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) - * lir::OperandTypeCount * lir::OperandTypeCount]; + * lir::Operand::TypeCount * lir::Operand::TypeCount]; BranchOperationType branchOperations[lir::BranchOperationCount - * lir::OperandTypeCount - * lir::OperandTypeCount]; + * lir::Operand::TypeCount + * lir::Operand::TypeCount]; }; class Context { diff --git a/src/codegen/target/x86/multimethod.cpp b/src/codegen/target/x86/multimethod.cpp index 19e6135e1a..17bc3d91cc 100644 --- a/src/codegen/target/x86/multimethod.cpp +++ b/src/codegen/target/x86/multimethod.cpp @@ -28,42 +28,42 @@ using namespace util; unsigned index(ArchitectureContext*, lir::BinaryOperation operation, - lir::OperandType operand1, - lir::OperandType operand2) + lir::Operand::Type operand1, + lir::Operand::Type operand2) { return operation + ((lir::BinaryOperationCount - + lir::NonBranchTernaryOperationCount) * operand1) + + lir::NonBranchTernaryOperationCount) * (unsigned)operand1) + ((lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) - * lir::OperandTypeCount * operand2); + * lir::Operand::TypeCount * (unsigned)operand2); } unsigned index(ArchitectureContext* c UNUSED, lir::TernaryOperation operation, - lir::OperandType operand1, - lir::OperandType operand2) + lir::Operand::Type operand1, + lir::Operand::Type operand2) { assertT(c, not isBranch(operation)); return lir::BinaryOperationCount + operation + ((lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) - * operand1) + * (unsigned)operand1) + ((lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) - * lir::OperandTypeCount * operand2); + * lir::Operand::TypeCount * (unsigned)operand2); } unsigned branchIndex(ArchitectureContext* c UNUSED, - lir::OperandType operand1, - lir::OperandType operand2) + lir::Operand::Type operand1, + lir::Operand::Type operand2) { - return operand1 + (lir::OperandTypeCount * operand2); + return (unsigned)operand1 + (lir::Operand::TypeCount * (unsigned)operand2); } void populateTables(ArchitectureContext* c) { - const lir::OperandType C = lir::ConstantOperand; - const lir::OperandType A = lir::AddressOperand; - const lir::OperandType R = lir::RegisterOperand; - const lir::OperandType M = lir::MemoryOperand; + const lir::Operand::Type C = lir::Operand::Type::Constant; + const lir::Operand::Type A = lir::Operand::Type::Address; + const lir::Operand::Type R = lir::Operand::Type::RegisterPair; + const lir::Operand::Type M = lir::Operand::Type::Memory; OperationType* zo = c->operations; UnaryOperationType* uo = c->unaryOperations; diff --git a/src/codegen/target/x86/multimethod.h b/src/codegen/target/x86/multimethod.h index e9a4b36de6..5816ccb543 100644 --- a/src/codegen/target/x86/multimethod.h +++ b/src/codegen/target/x86/multimethod.h @@ -23,17 +23,17 @@ class ArchitectureContext; unsigned index(ArchitectureContext*, lir::BinaryOperation operation, - lir::OperandType operand1, - lir::OperandType operand2); + lir::Operand::Type operand1, + lir::Operand::Type operand2); unsigned index(ArchitectureContext* c UNUSED, lir::TernaryOperation operation, - lir::OperandType operand1, - lir::OperandType operand2); + lir::Operand::Type operand1, + lir::Operand::Type operand2); unsigned branchIndex(ArchitectureContext* c UNUSED, - lir::OperandType operand1, - lir::OperandType operand2); + lir::Operand::Type operand1, + lir::Operand::Type operand2); void populateTables(ArchitectureContext* c); diff --git a/src/compile.cpp b/src/compile.cpp index b64d06f1c5..a3f6e47cae 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -9785,20 +9785,20 @@ void compileCall(MyThread* t, Context* c, ThunkIndex index, bool call = true) lir::Memory table(t->arch->thread(), TARGET_THREAD_THUNKTABLE); lir::Register scratch(t->arch->scratch()); a->apply(lir::Move, - OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &table), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &scratch)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Memory, &table), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &scratch)); lir::Memory proc(scratch.low, index * TargetBytesPerWord); a->apply(lir::Move, - OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &proc), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &scratch)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Memory, &proc), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &scratch)); a->apply(call ? lir::Call : lir::Jump, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &scratch)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &scratch)); } else { lir::Constant proc(new (&c->zone) avian::codegen::ResolvedPromise( reinterpret_cast(t->thunkTable[index]))); a->apply(call ? lir::LongCall : lir::LongJump, - OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &proc)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Constant, &proc)); } } @@ -9815,7 +9815,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.default_.frameSavedOffset = a->length(); lir::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, compileMethodIndex); @@ -9823,7 +9823,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) lir::Register result(t->arch->returnLow()); a->apply(lir::Jump, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &result)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &result)); p->thunks.default_.length = a->endBlock(false)->resolve(0, 0); @@ -9843,17 +9843,17 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) a->apply(lir::Move, OperandInfo( - TargetBytesPerWord, lir::MemoryOperand, &virtualCallTargetSrc), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &class_)); + TargetBytesPerWord, lir::Operand::Type::Memory, &virtualCallTargetSrc), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &class_)); lir::Memory virtualCallTargetDst(t->arch->thread(), TARGET_THREAD_VIRTUALCALLTARGET); a->apply( lir::Move, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &class_), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &class_), OperandInfo( - TargetBytesPerWord, lir::MemoryOperand, &virtualCallTargetDst)); + TargetBytesPerWord, lir::Operand::Type::Memory, &virtualCallTargetDst)); lir::Register index(t->arch->virtualCallIndex()); lir::Memory virtualCallIndex(t->arch->thread(), @@ -9861,15 +9861,15 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) a->apply( lir::Move, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &index), - OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &virtualCallIndex)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &index), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Memory, &virtualCallIndex)); a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); p->thunks.defaultVirtual.frameSavedOffset = a->length(); lir::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, compileVirtualMethodIndex); @@ -9877,7 +9877,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) lir::Register result(t->arch->returnLow()); a->apply(lir::Jump, - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &result)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &result)); p->thunks.defaultVirtual.length = a->endBlock(false)->resolve(0, 0); @@ -9894,7 +9894,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.native.frameSavedOffset = a->length(); lir::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, invokeNativeIndex); @@ -9916,7 +9916,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.aioob.frameSavedOffset = a->length(); lir::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, throwArrayIndexOutOfBoundsIndex); @@ -9935,7 +9935,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.stackOverflow.frameSavedOffset = a->length(); lir::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, throwStackOverflowIndex); @@ -10061,14 +10061,14 @@ uintptr_t compileVirtualThunk(MyThread* t, unsigned index, unsigned* size) lir::Register indexRegister(t->arch->virtualCallIndex()); a->apply( lir::Move, - OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &indexConstant), - OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &indexRegister)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Constant, &indexConstant), + OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &indexRegister)); avian::codegen::ResolvedPromise defaultVirtualThunkPromise( defaultVirtualThunk(t)); lir::Constant thunk(&defaultVirtualThunkPromise); a->apply(lir::Jump, - OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &thunk)); + OperandInfo(TargetBytesPerWord, lir::Operand::Type::Constant, &thunk)); *size = a->endBlock(false)->resolve(0, 0); From 10442dc7d6eac89779920e8505ee1e40021c256f Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 18:33:44 -0700 Subject: [PATCH 16/70] finish renaming lir:: types (fixup arm) --- src/codegen/target/arm/multimethod.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen/target/arm/multimethod.cpp b/src/codegen/target/arm/multimethod.cpp index c01c934e5b..ec1d96491c 100644 --- a/src/codegen/target/arm/multimethod.cpp +++ b/src/codegen/target/arm/multimethod.cpp @@ -25,8 +25,8 @@ unsigned index(ArchitectureContext*, lir::Operand::Type operand1, lir::Operand::Type operand2) { - return operation + (lir::BinaryOperationCount * operand1) - + (lir::BinaryOperationCount * lir::Operand::TypeCount * operand2); + return operation + (lir::BinaryOperationCount * (unsigned)operand1) + + (lir::BinaryOperationCount * lir::Operand::TypeCount * (unsigned)operand2); } unsigned index(ArchitectureContext* con UNUSED, @@ -35,14 +35,14 @@ unsigned index(ArchitectureContext* con UNUSED, { assertT(con, not isBranch(operation)); - return operation + (lir::NonBranchTernaryOperationCount * operand1); + return operation + (lir::NonBranchTernaryOperationCount * (unsigned)operand1); } unsigned branchIndex(ArchitectureContext* con UNUSED, lir::Operand::Type operand1, lir::Operand::Type operand2) { - return operand1 + (lir::Operand::TypeCount * operand2); + return (unsigned)operand1 + (lir::Operand::TypeCount * (unsigned)operand2); } void populateTables(ArchitectureContext* con) From 02d1a83ad9df97537984238e65498c0cbb8eef71 Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 18:45:57 -0700 Subject: [PATCH 17/70] rename lir::Register to lir::RegisterPair --- include/avian/codegen/lir.h | 4 +- src/codegen/compiler/site.cpp | 2 +- src/codegen/target/arm/assembler.cpp | 28 +-- src/codegen/target/arm/operations.cpp | 258 +++++++++++----------- src/codegen/target/arm/operations.h | 196 ++++++++--------- src/codegen/target/arm/registers.h | 6 +- src/codegen/target/x86/assembler.cpp | 36 +-- src/codegen/target/x86/encode.cpp | 36 +-- src/codegen/target/x86/encode.h | 34 +-- src/codegen/target/x86/operations.cpp | 302 +++++++++++++------------- src/codegen/target/x86/operations.h | 196 ++++++++--------- src/compile.cpp | 22 +- 12 files changed, 560 insertions(+), 560 deletions(-) diff --git a/include/avian/codegen/lir.h b/include/avian/codegen/lir.h index 91b48fb96d..b5f9efe259 100644 --- a/include/avian/codegen/lir.h +++ b/include/avian/codegen/lir.h @@ -149,9 +149,9 @@ class Address : public Operand { Promise* address; }; -class Register : public Operand { +class RegisterPair : public Operand { public: - Register(int low, int high = NoRegister) : low(low), high(high) + RegisterPair(int low, int high = NoRegister) : low(low), high(high) { } diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 99ce5fb154..1b7880d2d0 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -349,7 +349,7 @@ void RegisterSite::asAssemblerOperand(Context* c UNUSED, highNumber = lir::NoRegister; } - new (result) lir::Register(number, highNumber); + new (result) lir::RegisterPair(number, highNumber); } Site* RegisterSite::copy(Context* c) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index c383aea819..bec887eab2 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -656,7 +656,7 @@ class MyAssembler : public Assembler { virtual void checkStackOverflow(uintptr_t handler, unsigned stackLimitOffsetFromThread) { - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); lir::Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread); lir::Constant handlerConstant(new (con.zone) ResolvedPromise(handler)); branchRM(&con, @@ -669,11 +669,11 @@ class MyAssembler : public Assembler { virtual void saveFrame(unsigned stackOffset, unsigned ipOffset) { - lir::Register link(LinkRegister); + lir::RegisterPair link(LinkRegister); lir::Memory linkDst(ThreadRegister, ipOffset); moveRM(&con, TargetBytesPerWord, &link, TargetBytesPerWord, &linkDst); - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); lir::Memory stackDst(ThreadRegister, stackOffset); moveRM(&con, TargetBytesPerWord, &stack, TargetBytesPerWord, &stackDst); } @@ -705,7 +705,7 @@ class MyAssembler : public Assembler { unsigned offset = 0; for (unsigned i = 0; i < argumentCount; ++i) { if (i < arch_->argumentRegisterCount()) { - lir::Register dst(arch_->argumentRegister(i)); + lir::RegisterPair dst(arch_->argumentRegister(i)); apply(lir::Move, OperandInfo(RUNTIME_ARRAY_BODY(arguments)[i].size, @@ -745,12 +745,12 @@ class MyAssembler : public Assembler { // how to handle them: assertT(&con, footprint < 256); - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); lir::Constant footprintConstant(&footprintPromise); subC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); - lir::Register returnAddress(LinkRegister); + lir::RegisterPair returnAddress(LinkRegister); lir::Memory returnAddressDst(StackRegister, (footprint - 1) * TargetBytesPerWord); moveRM(&con, @@ -762,7 +762,7 @@ class MyAssembler : public Assembler { virtual void adjustFrame(unsigned difference) { - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); ResolvedPromise differencePromise(difference * TargetBytesPerWord); lir::Constant differenceConstant(&differencePromise); subC(&con, TargetBytesPerWord, &differenceConstant, &stack, &stack); @@ -772,7 +772,7 @@ class MyAssembler : public Assembler { { footprint += FrameHeaderSize; - lir::Register returnAddress(LinkRegister); + lir::RegisterPair returnAddress(LinkRegister); lir::Memory returnAddressSrc(StackRegister, (footprint - 1) * TargetBytesPerWord); moveMR(&con, @@ -781,7 +781,7 @@ class MyAssembler : public Assembler { TargetBytesPerWord, &returnAddress); - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); lir::Constant footprintConstant(&footprintPromise); addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); @@ -798,7 +798,7 @@ class MyAssembler : public Assembler { if (offset) { footprint += FrameHeaderSize; - lir::Register link(LinkRegister); + lir::RegisterPair link(LinkRegister); lir::Memory returnAddressSrc(StackRegister, (footprint - 1) * TargetBytesPerWord); moveMR(&con, @@ -807,7 +807,7 @@ class MyAssembler : public Assembler { TargetBytesPerWord, &link); - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); ResolvedPromise footprintPromise((footprint - offset) * TargetBytesPerWord); lir::Constant footprintConstant(&footprintPromise); @@ -816,7 +816,7 @@ class MyAssembler : public Assembler { if (returnAddressSurrogate != lir::NoRegister) { assertT(&con, offset > 0); - lir::Register ras(returnAddressSurrogate); + lir::RegisterPair ras(returnAddressSurrogate); lir::Memory dst(StackRegister, (offset - 1) * TargetBytesPerWord); moveRM(&con, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } @@ -840,7 +840,7 @@ class MyAssembler : public Assembler { if (TailCalls and argumentFootprint > StackAlignmentInWords) { offset = argumentFootprint - StackAlignmentInWords; - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); ResolvedPromise adjustmentPromise(offset * TargetBytesPerWord); lir::Constant adjustment(&adjustmentPromise); addC(&con, TargetBytesPerWord, &adjustment, &stack, &stack); @@ -856,7 +856,7 @@ class MyAssembler : public Assembler { { popFrame(frameFootprint); - lir::Register stack(StackRegister); + lir::RegisterPair stack(StackRegister); lir::Memory newStackSrc(ThreadRegister, stackOffsetFromThread); moveMR(&con, TargetBytesPerWord, &newStackSrc, TargetBytesPerWord, &stack); diff --git a/src/codegen/target/arm/operations.cpp b/src/codegen/target/arm/operations.cpp index 8afe088729..1fa365c7b7 100644 --- a/src/codegen/target/arm/operations.cpp +++ b/src/codegen/target/arm/operations.cpp @@ -35,20 +35,20 @@ inline unsigned lo8(int64_t i) void andC(Context* con, unsigned size, lir::Constant* a, - lir::Register* b, - lir::Register* dst); + lir::RegisterPair* b, + lir::RegisterPair* dst); void shiftLeftR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); ResolvedPromise maskPromise(0x3F); lir::Constant mask(&maskPromise); - lir::Register dst(tmp3); + lir::RegisterPair dst(tmp3); andC(con, 4, &mask, a, &dst); emit(con, lsl(tmp1, b->high, tmp3)); emit(con, rsbi(tmp2, tmp3, 32)); @@ -64,7 +64,7 @@ void shiftLeftR(Context* con, int tmp = newTemp(con); ResolvedPromise maskPromise(0x1F); lir::Constant mask(&maskPromise); - lir::Register dst(tmp); + lir::RegisterPair dst(tmp); andC(con, size, &mask, a, &dst); emit(con, lsl(t->low, b->low, tmp)); freeTemp(con, tmp); @@ -73,15 +73,15 @@ void shiftLeftR(Context* con, void moveRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize, - lir::Register* dst); + lir::RegisterPair* dst); void shiftLeftC(Context* con, unsigned size UNUSED, lir::Constant* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* b, + lir::RegisterPair* t) { assertT(con, size == vm::TargetBytesPerWord); if (getValue(a) & 0x1F) { @@ -93,15 +93,15 @@ void shiftLeftC(Context* con, void shiftRightR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); ResolvedPromise maskPromise(0x3F); lir::Constant mask(&maskPromise); - lir::Register dst(tmp3); + lir::RegisterPair dst(tmp3); andC(con, 4, &mask, a, &dst); emit(con, lsr(tmp1, b->low, tmp3)); emit(con, rsbi(tmp2, tmp3, 32)); @@ -117,7 +117,7 @@ void shiftRightR(Context* con, int tmp = newTemp(con); ResolvedPromise maskPromise(0x1F); lir::Constant mask(&maskPromise); - lir::Register dst(tmp); + lir::RegisterPair dst(tmp); andC(con, size, &mask, a, &dst); emit(con, asr(t->low, b->low, tmp)); freeTemp(con, tmp); @@ -127,8 +127,8 @@ void shiftRightR(Context* con, void shiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* b, + lir::RegisterPair* t) { assertT(con, size == vm::TargetBytesPerWord); if (getValue(a) & 0x1F) { @@ -140,14 +140,14 @@ void shiftRightC(Context* con, void unsignedShiftRightR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { int tmpShift = newTemp(con); ResolvedPromise maskPromise(size == 8 ? 0x3F : 0x1F); lir::Constant mask(&maskPromise); - lir::Register dst(tmpShift); + lir::RegisterPair dst(tmpShift); andC(con, 4, &mask, a, &dst); emit(con, lsr(t->low, b->low, tmpShift)); if (size == 8) { @@ -168,8 +168,8 @@ void unsignedShiftRightR(Context* con, void unsignedShiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* b, + lir::RegisterPair* t) { assertT(con, size == vm::TargetBytesPerWord); if (getValue(a) & 0x1F) { @@ -274,7 +274,7 @@ void resolve(MyBlock* b) } } -void jumpR(Context* con, unsigned size UNUSED, lir::Register* target) +void jumpR(Context* con, unsigned size UNUSED, lir::RegisterPair* target) { assertT(con, size == vm::TargetBytesPerWord); emit(con, bx(target->low)); @@ -282,14 +282,14 @@ void jumpR(Context* con, unsigned size UNUSED, lir::Register* target) void swapRR(Context* con, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(con, aSize == vm::TargetBytesPerWord); assertT(con, bSize == vm::TargetBytesPerWord); - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); moveRR(con, aSize, a, bSize, &tmp); moveRR(con, bSize, b, aSize, a); moveRR(con, bSize, &tmp, bSize, b); @@ -298,9 +298,9 @@ void swapRR(Context* con, void moveRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize, - lir::Register* dst) + lir::RegisterPair* dst) { bool srcIsFpr = isFpr(src); bool dstIsFpr = isFpr(dst); @@ -343,8 +343,8 @@ void moveRR(Context* con, moveRR(con, 4, src, 4, dst); emit(con, asri(dst->high, src->low, 31)); } else if (srcSize == 8 and dstSize == 8) { - lir::Register srcHigh(src->high); - lir::Register dstHigh(dst->high); + lir::RegisterPair srcHigh(src->high); + lir::RegisterPair dstHigh(dst->high); if (src->high == dst->low) { if (src->low == dst->high) { @@ -369,9 +369,9 @@ void moveRR(Context* con, void moveZRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned, - lir::Register* dst) + lir::RegisterPair* dst) { switch (srcSize) { case 2: @@ -388,16 +388,16 @@ void moveCR(Context* con, unsigned size, lir::Constant* src, unsigned, - lir::Register* dst); + lir::RegisterPair* dst); void moveCR2(Context* con, unsigned size, lir::Constant* src, - lir::Register* dst, + lir::RegisterPair* dst, Promise* callOffset) { if (isFpr(dst)) { // floating-point - lir::Register tmp = size > 4 ? makeTemp64(con) : makeTemp(con); + lir::RegisterPair tmp = size > 4 ? makeTemp64(con) : makeTemp(con); moveCR(con, size, src, size, &tmp); moveRR(con, size, &tmp, size, dst); freeTemp(con, tmp); @@ -407,7 +407,7 @@ void moveCR2(Context* con, lir::Constant srcLo(&loBits); ResolvedPromise hiBits(value >> 32); lir::Constant srcHi(&hiBits); - lir::Register dstHi(dst->high); + lir::RegisterPair dstHi(dst->high); moveCR(con, 4, &srcLo, 4, dst); moveCR(con, 4, &srcHi, 4, &dstHi); } else if (src->value->resolved() and isOfWidth(getValue(src), 8)) { @@ -422,16 +422,16 @@ void moveCR(Context* con, unsigned size, lir::Constant* src, unsigned, - lir::Register* dst) + lir::RegisterPair* dst) { moveCR2(con, size, src, dst, 0); } void addR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { emit(con, SETS(add(t->low, a->low, b->low))); @@ -443,9 +443,9 @@ void addR(Context* con, void subR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { emit(con, SETS(rsb(t->low, a->low, b->low))); @@ -458,8 +458,8 @@ void subR(Context* con, void addC(Context* con, unsigned size, lir::Constant* a, - lir::Register* b, - lir::Register* dst) + lir::RegisterPair* b, + lir::RegisterPair* dst) { assertT(con, size == vm::TargetBytesPerWord); @@ -481,8 +481,8 @@ void addC(Context* con, void subC(Context* con, unsigned size, lir::Constant* a, - lir::Register* b, - lir::Register* dst) + lir::RegisterPair* b, + lir::RegisterPair* dst) { assertT(con, size == vm::TargetBytesPerWord); @@ -503,9 +503,9 @@ void subC(Context* con, void multiplyR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { bool useTemporaries = b->low == t->low; @@ -531,9 +531,9 @@ void multiplyR(Context* con, void floatAbsoluteRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b) + lir::RegisterPair* b) { if (size == 8) { emit(con, fabsd(fpr64(b), fpr64(a))); @@ -544,9 +544,9 @@ void floatAbsoluteRR(Context* con, void floatNegateRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b) + lir::RegisterPair* b) { if (size == 8) { emit(con, fnegd(fpr64(b), fpr64(a))); @@ -557,9 +557,9 @@ void floatNegateRR(Context* con, void float2FloatRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b) + lir::RegisterPair* b) { if (size == 8) { emit(con, fcvtsd(fpr32(b), fpr64(a))); @@ -570,9 +570,9 @@ void float2FloatRR(Context* con, void float2IntRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b) + lir::RegisterPair* b) { int tmp = newTemp(con, FPR_MASK); int ftmp = fpr32(tmp); @@ -587,9 +587,9 @@ void float2IntRR(Context* con, void int2FloatRR(Context* con, unsigned, - lir::Register* a, + lir::RegisterPair* a, unsigned size, - lir::Register* b) + lir::RegisterPair* b) { emit(con, fmsr(fpr32(b), a->low)); if (size == 8) { // int to double @@ -601,9 +601,9 @@ void int2FloatRR(Context* con, void floatSqrtRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b) + lir::RegisterPair* b) { if (size == 8) { emit(con, fsqrtd(fpr64(b), fpr64(a))); @@ -614,9 +614,9 @@ void floatSqrtRR(Context* con, void floatAddR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { emit(con, faddd(fpr64(t), fpr64(a), fpr64(b))); @@ -627,9 +627,9 @@ void floatAddR(Context* con, void floatSubtractR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { emit(con, fsubd(fpr64(t), fpr64(b), fpr64(a))); @@ -640,9 +640,9 @@ void floatSubtractR(Context* con, void floatMultiplyR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { emit(con, fmuld(fpr64(t), fpr64(a), fpr64(b))); @@ -653,9 +653,9 @@ void floatMultiplyR(Context* con, void floatDivideR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t) { if (size == 8) { emit(con, fdivd(fpr64(t), fpr64(b), fpr64(a))); @@ -672,7 +672,7 @@ int normalize(Context* con, bool* release) { if (offset != 0 or scale != 1) { - lir::Register normalizedIndex( + lir::RegisterPair normalizedIndex( *preserveIndex ? con->client->acquireTemporary(GPR_MASK) : index); if (*preserveIndex) { @@ -685,7 +685,7 @@ int normalize(Context* con, int scaled; if (scale != 1) { - lir::Register unscaledIndex(index); + lir::RegisterPair unscaledIndex(index); ResolvedPromise scalePromise(log(scale)); lir::Constant scaleConstant(&scalePromise); @@ -702,12 +702,12 @@ int normalize(Context* con, } if (offset != 0) { - lir::Register untranslatedIndex(scaled); + lir::RegisterPair untranslatedIndex(scaled); ResolvedPromise offsetPromise(offset); lir::Constant offsetConstant(&offsetPromise); - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); moveCR(con, vm::TargetBytesPerWord, &offsetConstant, @@ -730,7 +730,7 @@ int normalize(Context* con, void store(Context* con, unsigned size, - lir::Register* src, + lir::RegisterPair* src, int base, int offset, int index, @@ -757,7 +757,7 @@ void store(Context* con, break; case 8: { // split into 2 32-bit stores - lir::Register srcHigh(src->high); + lir::RegisterPair srcHigh(src->high); store(con, 4, &srcHigh, base, 0, normalized, 1, preserveIndex); store(con, 4, src, base, 4, normalized, 1, preserveIndex); } break; @@ -766,7 +766,7 @@ void store(Context* con, abort(con); } } else { // FPR store - lir::Register base_(base), normalized_(normalized), + lir::RegisterPair base_(base), normalized_(normalized), absAddr = makeTemp(con); // FPR stores have only bases, so we must add the index addR(con, vm::TargetBytesPerWord, &base_, &normalized_, &absAddr); @@ -798,7 +798,7 @@ void store(Context* con, break; case 8: { // split into 2 32-bit stores - lir::Register srcHigh(src->high); + lir::RegisterPair srcHigh(src->high); store(con, 4, &srcHigh, base, offset, lir::NoRegister, 1, false); store(con, 4, src, base, offset + 4, lir::NoRegister, 1, false); } break; @@ -815,7 +815,7 @@ void store(Context* con, emit(con, fsts(fpr32(src), base, offset)); } } else { - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); ResolvedPromise offsetPromise(offset); lir::Constant offsetConstant(&offsetPromise); moveCR(con, @@ -832,7 +832,7 @@ void store(Context* con, void moveRM(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize UNUSED, lir::Memory* dst) { @@ -849,7 +849,7 @@ void load(Context* con, int index, unsigned scale, unsigned dstSize, - lir::Register* dst, + lir::RegisterPair* dst, bool preserveIndex, bool signExtend) { @@ -882,7 +882,7 @@ void load(Context* con, load(con, 4, base, 0, normalized, 1, 4, dst, preserveIndex, false); moveRR(con, 4, dst, 8, dst); } else if (srcSize == 8 and dstSize == 8) { - lir::Register dstHigh(dst->high); + lir::RegisterPair dstHigh(dst->high); load(con, 4, base, @@ -903,7 +903,7 @@ void load(Context* con, abort(con); } } else { // FPR load - lir::Register base_(base), normalized_(normalized), + lir::RegisterPair base_(base), normalized_(normalized), absAddr = makeTemp(con); // VFP loads only have bases, so we must add the index addR(con, vm::TargetBytesPerWord, &base_, &normalized_, &absAddr); @@ -946,7 +946,7 @@ void load(Context* con, case 8: { if (dstSize == 8) { - lir::Register dstHigh(dst->high); + lir::RegisterPair dstHigh(dst->high); load(con, 4, base, @@ -984,7 +984,7 @@ void load(Context* con, emit(con, flds(fpr32(dst), base, offset)); } } else { - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); ResolvedPromise offsetPromise(offset); lir::Constant offsetConstant(&offsetPromise); moveCR(con, @@ -1003,7 +1003,7 @@ void moveMR(Context* con, unsigned srcSize, lir::Memory* src, unsigned dstSize, - lir::Register* dst) + lir::RegisterPair* dst) { load(con, srcSize, @@ -1021,7 +1021,7 @@ void moveZMR(Context* con, unsigned srcSize, lir::Memory* src, unsigned dstSize, - lir::Register* dst) + lir::RegisterPair* dst) { load(con, srcSize, @@ -1037,9 +1037,9 @@ void moveZMR(Context* con, void andR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* dst) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) { if (size == 8) emit(con, and_(dst->high, a->high, b->high)); @@ -1049,8 +1049,8 @@ void andR(Context* con, void andC(Context* con, unsigned size, lir::Constant* a, - lir::Register* b, - lir::Register* dst) + lir::RegisterPair* b, + lir::RegisterPair* dst) { int64_t v = a->value->value(); @@ -1061,8 +1061,8 @@ void andC(Context* con, ResolvedPromise low(v & 0xFFFFFFFF); lir::Constant al(&low); - lir::Register bh(b->high); - lir::Register dh(dst->high); + lir::RegisterPair bh(b->high); + lir::RegisterPair dh(dst->high); andC(con, 4, &al, b, dst); andC(con, 4, &ah, &bh, &dh); @@ -1078,7 +1078,7 @@ void andC(Context* con, // instruction bool useTemporary = b->low == dst->low; - lir::Register tmp(dst->low); + lir::RegisterPair tmp(dst->low); if (useTemporary) { tmp.low = con->client->acquireTemporary(GPR_MASK); } @@ -1098,9 +1098,9 @@ void andC(Context* con, void orR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* dst) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) { if (size == 8) emit(con, orr(dst->high, a->high, b->high)); @@ -1109,9 +1109,9 @@ void orR(Context* con, void xorR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* dst) + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) { if (size == 8) emit(con, eor(dst->high, a->high, b->high)); @@ -1122,7 +1122,7 @@ void moveAR2(Context* con, unsigned srcSize, lir::Address* src, unsigned dstSize, - lir::Register* dst) + lir::RegisterPair* dst) { assertT(con, srcSize == 4 and dstSize == 4); @@ -1137,16 +1137,16 @@ void moveAR(Context* con, unsigned srcSize, lir::Address* src, unsigned dstSize, - lir::Register* dst) + lir::RegisterPair* dst) { moveAR2(con, srcSize, src, dstSize, dst); } void compareRR(Context* con, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(con, !(isFpr(a) ^ isFpr(b))); // regs must be of the same type @@ -1168,14 +1168,14 @@ void compareCR(Context* con, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(con, aSize == 4 and bSize == 4); if (!isFpr(b) && a->value->resolved() && isOfWidth(a->value->value(), 8)) { emit(con, cmpi(b->low, a->value->value())); } else { - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); moveCR(con, aSize, a, bSize, &tmp); compareRR(con, bSize, &tmp, bSize, b); con->client->releaseTemporary(tmp.low); @@ -1190,7 +1190,7 @@ void compareCM(Context* con, { assertT(con, aSize == 4 and bSize == 4); - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); moveMR(con, bSize, b, bSize, &tmp); compareCR(con, aSize, a, bSize, &tmp); con->client->releaseTemporary(tmp.low); @@ -1198,13 +1198,13 @@ void compareCM(Context* con, void compareRM(Context* con, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, lir::Memory* b) { assertT(con, aSize == 4 and bSize == 4); - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); moveMR(con, bSize, b, bSize, &tmp); compareRR(con, aSize, a, bSize, &tmp); con->client->releaseTemporary(tmp.low); @@ -1352,13 +1352,13 @@ void branchLong(Context* con, void branchRR(Context* con, lir::TernaryOperation op, unsigned size, - lir::Register* a, - lir::Register* b, + lir::RegisterPair* a, + lir::RegisterPair* b, lir::Constant* target) { if (!isFpr(a) && size > vm::TargetBytesPerWord) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); branchLong( con, op, a, &ah, b, &bh, target, CAST2(compareRR), CAST2(compareRR)); @@ -1372,7 +1372,7 @@ void branchCR(Context* con, lir::TernaryOperation op, unsigned size, lir::Constant* a, - lir::Register* b, + lir::RegisterPair* b, lir::Constant* target) { assertT(con, !isFloatBranch(op)); @@ -1386,7 +1386,7 @@ void branchCR(Context* con, ResolvedPromise high((v >> 32) & ~static_cast(0)); lir::Constant ah(&high); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); branchLong( con, op, &al, &ah, b, &bh, target, CAST2(compareCR), CAST2(compareCR)); @@ -1399,7 +1399,7 @@ void branchCR(Context* con, void branchRM(Context* con, lir::TernaryOperation op, unsigned size, - lir::Register* a, + lir::RegisterPair* a, lir::Memory* b, lir::Constant* target) { @@ -1450,7 +1450,7 @@ void moveCM(Context* con, } break; default: - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(con->client->acquireTemporary(GPR_MASK)); moveCR(con, srcSize, src, dstSize, &tmp); moveRM(con, dstSize, &tmp, dstSize, dst); con->client->releaseTemporary(tmp.low); @@ -1459,9 +1459,9 @@ void moveCM(Context* con, void negateRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize UNUSED, - lir::Register* dst) + lir::RegisterPair* dst) { assertT(con, srcSize == dstSize); @@ -1473,7 +1473,7 @@ void negateRR(Context* con, } } -void callR(Context* con, unsigned size UNUSED, lir::Register* target) +void callR(Context* con, unsigned size UNUSED, lir::RegisterPair* target) { assertT(con, size == vm::TargetBytesPerWord); emit(con, blx(target->low)); @@ -1491,7 +1491,7 @@ void longCallC(Context* con, unsigned size UNUSED, lir::Constant* target) { assertT(con, size == vm::TargetBytesPerWord); - lir::Register tmp(4); + lir::RegisterPair tmp(4); moveCR2(con, vm::TargetBytesPerWord, target, &tmp, offsetPromise(con)); callR(con, vm::TargetBytesPerWord, &tmp); } @@ -1500,7 +1500,7 @@ void longJumpC(Context* con, unsigned size UNUSED, lir::Constant* target) { assertT(con, size == vm::TargetBytesPerWord); - lir::Register tmp(4); // a non-arg reg that we don't mind clobbering + lir::RegisterPair tmp(4); // a non-arg reg that we don't mind clobbering moveCR2(con, vm::TargetBytesPerWord, target, &tmp, offsetPromise(con)); jumpR(con, vm::TargetBytesPerWord, &tmp); } diff --git a/src/codegen/target/arm/operations.h b/src/codegen/target/arm/operations.h index af2c70fc46..4135bedbf4 100644 --- a/src/codegen/target/arm/operations.h +++ b/src/codegen/target/arm/operations.h @@ -45,19 +45,19 @@ inline int64_t getValue(lir::Constant* con) return con->value->value(); } -inline lir::Register makeTemp(Context* con) +inline lir::RegisterPair makeTemp(Context* con) { - lir::Register tmp(newTemp(con)); + lir::RegisterPair tmp(newTemp(con)); return tmp; } -inline lir::Register makeTemp64(Context* con) +inline lir::RegisterPair makeTemp64(Context* con) { - lir::Register tmp(newTemp(con), newTemp(con)); + lir::RegisterPair tmp(newTemp(con), newTemp(con)); return tmp; } -inline void freeTemp(Context* con, const lir::Register& tmp) +inline void freeTemp(Context* con, const lir::RegisterPair& tmp) { if (tmp.low != lir::NoRegister) freeTemp(con, tmp.low); @@ -67,45 +67,45 @@ inline void freeTemp(Context* con, const lir::Register& tmp) void shiftLeftR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void moveRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize, - lir::Register* dst); + lir::RegisterPair* dst); void shiftLeftC(Context* con, unsigned size UNUSED, lir::Constant* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* b, + lir::RegisterPair* t); void shiftRightR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void shiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* b, + lir::RegisterPair* t); void unsignedShiftRightR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void unsignedShiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* b, + lir::RegisterPair* t); bool needJump(MyBlock* b); @@ -113,133 +113,133 @@ unsigned padding(MyBlock* b, unsigned offset); void resolve(MyBlock* b); -void jumpR(Context* con, unsigned size UNUSED, lir::Register* target); +void jumpR(Context* con, unsigned size UNUSED, lir::RegisterPair* target); void swapRR(Context* con, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void moveRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize, - lir::Register* dst); + lir::RegisterPair* dst); void moveZRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned, - lir::Register* dst); + lir::RegisterPair* dst); void moveCR(Context* con, unsigned size, lir::Constant* src, unsigned, - lir::Register* dst); + lir::RegisterPair* dst); void moveCR2(Context* con, unsigned size, lir::Constant* src, - lir::Register* dst, + lir::RegisterPair* dst, Promise* callOffset); void moveCR(Context* con, unsigned size, lir::Constant* src, unsigned, - lir::Register* dst); + lir::RegisterPair* dst); void addR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void subR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void addC(Context* con, unsigned size, lir::Constant* a, - lir::Register* b, - lir::Register* dst); + lir::RegisterPair* b, + lir::RegisterPair* dst); void subC(Context* con, unsigned size, lir::Constant* a, - lir::Register* b, - lir::Register* dst); + lir::RegisterPair* b, + lir::RegisterPair* dst); void multiplyR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void floatAbsoluteRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b); + lir::RegisterPair* b); void floatNegateRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b); + lir::RegisterPair* b); void float2FloatRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b); + lir::RegisterPair* b); void float2IntRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b); + lir::RegisterPair* b); void int2FloatRR(Context* con, unsigned, - lir::Register* a, + lir::RegisterPair* a, unsigned size, - lir::Register* b); + lir::RegisterPair* b); void floatSqrtRR(Context* con, unsigned size, - lir::Register* a, + lir::RegisterPair* a, unsigned, - lir::Register* b); + lir::RegisterPair* b); void floatAddR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void floatSubtractR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void floatMultiplyR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); void floatDivideR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* t); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* t); int normalize(Context* con, int offset, @@ -250,7 +250,7 @@ int normalize(Context* con, void store(Context* con, unsigned size, - lir::Register* src, + lir::RegisterPair* src, int base, int offset, int index, @@ -259,7 +259,7 @@ void store(Context* con, void moveRM(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize UNUSED, lir::Memory* dst); @@ -270,7 +270,7 @@ void load(Context* con, int index, unsigned scale, unsigned dstSize, - lir::Register* dst, + lir::RegisterPair* dst, bool preserveIndex, bool signExtend); @@ -278,61 +278,61 @@ void moveMR(Context* con, unsigned srcSize, lir::Memory* src, unsigned dstSize, - lir::Register* dst); + lir::RegisterPair* dst); void moveZMR(Context* con, unsigned srcSize, lir::Memory* src, unsigned dstSize, - lir::Register* dst); + lir::RegisterPair* dst); void andR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* dst); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst); void andC(Context* con, unsigned size, lir::Constant* a, - lir::Register* b, - lir::Register* dst); + lir::RegisterPair* b, + lir::RegisterPair* dst); void orR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* dst); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst); void xorR(Context* con, unsigned size, - lir::Register* a, - lir::Register* b, - lir::Register* dst); + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst); void moveAR2(Context* con, unsigned srcSize, lir::Address* src, unsigned dstSize, - lir::Register* dst); + lir::RegisterPair* dst); void moveAR(Context* con, unsigned srcSize, lir::Address* src, unsigned dstSize, - lir::Register* dst); + lir::RegisterPair* dst); void compareRR(Context* con, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void compareCR(Context* con, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void compareCM(Context* con, unsigned aSize, @@ -342,7 +342,7 @@ void compareCM(Context* con, void compareRM(Context* con, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, lir::Memory* b); @@ -365,21 +365,21 @@ void branchLong(Context* con, void branchRR(Context* con, lir::TernaryOperation op, unsigned size, - lir::Register* a, - lir::Register* b, + lir::RegisterPair* a, + lir::RegisterPair* b, lir::Constant* target); void branchCR(Context* con, lir::TernaryOperation op, unsigned size, lir::Constant* a, - lir::Register* b, + lir::RegisterPair* b, lir::Constant* target); void branchRM(Context* con, lir::TernaryOperation op, unsigned size, - lir::Register* a, + lir::RegisterPair* a, lir::Memory* b, lir::Constant* target); @@ -403,11 +403,11 @@ void moveCM(Context* con, void negateRR(Context* con, unsigned srcSize, - lir::Register* src, + lir::RegisterPair* src, unsigned dstSize UNUSED, - lir::Register* dst); + lir::RegisterPair* dst); -void callR(Context* con, unsigned size UNUSED, lir::Register* target); +void callR(Context* con, unsigned size UNUSED, lir::RegisterPair* target); void callC(Context* con, unsigned size UNUSED, lir::Constant* target); diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index c47f2ae8c5..7d94af2349 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -26,7 +26,7 @@ const int N_FPRS = 16; const RegisterMask GPR_MASK = 0xffff; const RegisterMask FPR_MASK = 0xffff0000; -inline bool isFpr(lir::Register* reg) +inline bool isFpr(lir::RegisterPair* reg) { return reg->low >= N_GPRS; } @@ -35,7 +35,7 @@ inline int fpr64(int reg) { return reg - N_GPRS; } -inline int fpr64(lir::Register* reg) +inline int fpr64(lir::RegisterPair* reg) { return fpr64(reg->low); } @@ -43,7 +43,7 @@ inline int fpr32(int reg) { return fpr64(reg) << 1; } -inline int fpr32(lir::Register* reg) +inline int fpr32(lir::RegisterPair* reg) { return fpr64(reg) << 1; } diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index 4049683651..e91ffc6c8b 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -902,7 +902,7 @@ class MyAssembler : public Assembler { virtual void checkStackOverflow(uintptr_t handler, unsigned stackLimitOffsetFromThread) { - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); lir::Memory stackLimit(rbx, stackLimitOffsetFromThread); lir::Constant handlerConstant(resolvedPromise(&c, handler)); branchRM(&c, @@ -915,7 +915,7 @@ class MyAssembler : public Assembler { virtual void saveFrame(unsigned stackOffset, unsigned) { - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); lir::Memory stackDst(rbx, stackOffset); apply(lir::Move, OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack), @@ -949,7 +949,7 @@ class MyAssembler : public Assembler { unsigned offset = 0; for (unsigned i = 0; i < argumentCount; ++i) { if (i < arch_->argumentRegisterCount()) { - lir::Register dst(arch_->argumentRegister(i)); + lir::RegisterPair dst(arch_->argumentRegister(i)); apply(lir::Move, OperandInfo(RUNTIME_ARRAY_BODY(arguments)[i].size, RUNTIME_ARRAY_BODY(arguments)[i].type, @@ -976,10 +976,10 @@ class MyAssembler : public Assembler { virtual void allocateFrame(unsigned footprint) { - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); if (UseFramePointer) { - lir::Register base(rbp); + lir::RegisterPair base(rbp); pushR(&c, TargetBytesPerWord, &base); apply(lir::Move, @@ -998,7 +998,7 @@ class MyAssembler : public Assembler { virtual void adjustFrame(unsigned difference) { - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); lir::Constant differenceConstant( resolvedPromise(&c, difference * TargetBytesPerWord)); apply(lir::Subtract, @@ -1011,15 +1011,15 @@ class MyAssembler : public Assembler { virtual void popFrame(unsigned frameFootprint) { if (UseFramePointer) { - lir::Register base(rbp); - lir::Register stack(rsp); + lir::RegisterPair base(rbp); + lir::RegisterPair stack(rsp); apply(lir::Move, OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &base), OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &stack)); popR(&c, TargetBytesPerWord, &base); } else { - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); lir::Constant footprint( resolvedPromise(&c, frameFootprint * TargetBytesPerWord)); apply(lir::Add, @@ -1036,7 +1036,7 @@ class MyAssembler : public Assembler { { if (TailCalls) { if (offset) { - lir::Register tmp(c.client->acquireTemporary()); + lir::RegisterPair tmp(c.client->acquireTemporary()); unsigned baseSize = UseFramePointer ? 1 : 0; @@ -1060,11 +1060,11 @@ class MyAssembler : public Assembler { if (UseFramePointer) { lir::Memory baseSrc(rsp, frameFootprint * TargetBytesPerWord); - lir::Register base(rbp); + lir::RegisterPair base(rbp); moveMR(&c, TargetBytesPerWord, &baseSrc, TargetBytesPerWord, &base); } - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); lir::Constant footprint(resolvedPromise( &c, (frameFootprint - offset + baseSize) * TargetBytesPerWord)); @@ -1073,7 +1073,7 @@ class MyAssembler : public Assembler { if (returnAddressSurrogate != lir::NoRegister) { assertT(&c, offset > 0); - lir::Register ras(returnAddressSurrogate); + lir::RegisterPair ras(returnAddressSurrogate); lir::Memory dst(rsp, offset * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } @@ -1081,7 +1081,7 @@ class MyAssembler : public Assembler { if (framePointerSurrogate != lir::NoRegister) { assertT(&c, offset > 0); - lir::Register fps(framePointerSurrogate); + lir::RegisterPair fps(framePointerSurrogate); lir::Memory dst(rsp, (offset - 1) * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &fps, TargetBytesPerWord, &dst); } @@ -1102,10 +1102,10 @@ class MyAssembler : public Assembler { assertT(&c, (argumentFootprint % StackAlignmentInWords) == 0); if (TailCalls and argumentFootprint > StackAlignmentInWords) { - lir::Register returnAddress(rcx); + lir::RegisterPair returnAddress(rcx); popR(&c, TargetBytesPerWord, &returnAddress); - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); lir::Constant adjustment(resolvedPromise( &c, (argumentFootprint - StackAlignmentInWords) * TargetBytesPerWord)); @@ -1122,10 +1122,10 @@ class MyAssembler : public Assembler { { popFrame(frameFootprint); - lir::Register returnAddress(rcx); + lir::RegisterPair returnAddress(rcx); popR(&c, TargetBytesPerWord, &returnAddress); - lir::Register stack(rsp); + lir::RegisterPair stack(rsp); lir::Memory stackSrc(rbx, stackOffsetFromThread); moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &stack); diff --git a/src/codegen/target/x86/encode.cpp b/src/codegen/target/x86/encode.cpp index f64d91a2c9..7911bb7cc1 100644 --- a/src/codegen/target/x86/encode.cpp +++ b/src/codegen/target/x86/encode.cpp @@ -76,22 +76,22 @@ void maybeRex(Context* c, } } -void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Register* b) +void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b) { maybeRex(c, size, a->low, lir::NoRegister, b->low, false); } -void alwaysRex(Context* c, unsigned size, lir::Register* a, lir::Register* b) +void alwaysRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b) { maybeRex(c, size, a->low, lir::NoRegister, b->low, true); } -void maybeRex(Context* c, unsigned size, lir::Register* a) +void maybeRex(Context* c, unsigned size, lir::RegisterPair* a) { maybeRex(c, size, lir::NoRegister, lir::NoRegister, a->low, false); } -void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Memory* b) +void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b) { maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low & 4)); } @@ -106,7 +106,7 @@ void modrm(Context* c, uint8_t mod, int a, int b) c->code.append(mod | (regCode(b) << 3) | regCode(a)); } -void modrm(Context* c, uint8_t mod, lir::Register* a, lir::Register* b) +void modrm(Context* c, uint8_t mod, lir::RegisterPair* a, lir::RegisterPair* b) { modrm(c, mod, a->low, b->low); } @@ -143,7 +143,7 @@ void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset) } } -void modrmSibImm(Context* c, lir::Register* a, lir::Memory* b) +void modrmSibImm(Context* c, lir::RegisterPair* a, lir::Memory* b) { modrmSibImm(c, a->low, b->scale, b->index, b->base, b->offset); } @@ -177,9 +177,9 @@ void conditional(Context* c, unsigned condition, lir::Constant* a) void sseMoveRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize >= 4); assertT(c, aSize == bSize); @@ -213,10 +213,10 @@ void sseMoveCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize <= vm::TargetBytesPerWord); - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR2(c, aSize, a, aSize, &tmp, 0); sseMoveRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -226,7 +226,7 @@ void sseMoveMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize >= 4); @@ -244,7 +244,7 @@ void sseMoveMR(Context* c, void sseMoveRM(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, UNUSED unsigned bSize, lir::Memory* b) { @@ -353,9 +353,9 @@ void branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target) void floatRegOp(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b, + lir::RegisterPair* b, uint8_t op, uint8_t mod) { @@ -373,7 +373,7 @@ void floatMemOp(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b, + lir::RegisterPair* b, uint8_t op) { if (aSize == 4) { @@ -390,13 +390,13 @@ void moveCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void moveCR2(Context* c, UNUSED unsigned aSize, lir::Constant* a, UNUSED unsigned bSize, - lir::Register* b, + lir::RegisterPair* b, unsigned promiseOffset) { if (vm::TargetBytesPerWord == 4 and bSize == 8) { @@ -408,7 +408,7 @@ void moveCR2(Context* c, ResolvedPromise low(v & 0xFFFFFFFF); lir::Constant al(&low); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); moveCR(c, 4, &al, 4, b); moveCR(c, 4, &ah, 4, &bh); diff --git a/src/codegen/target/x86/encode.h b/src/codegen/target/x86/encode.h index 564b84f6e9..a51f27b725 100644 --- a/src/codegen/target/x86/encode.h +++ b/src/codegen/target/x86/encode.h @@ -32,13 +32,13 @@ void maybeRex(Context* c, int base, bool always); -void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Register* b); +void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b); -void alwaysRex(Context* c, unsigned size, lir::Register* a, lir::Register* b); +void alwaysRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b); -void maybeRex(Context* c, unsigned size, lir::Register* a); +void maybeRex(Context* c, unsigned size, lir::RegisterPair* a); -void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Memory* b); +void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b); void maybeRex(Context* c, unsigned size, lir::Memory* a); @@ -47,19 +47,19 @@ inline int regCode(int a) return a & 7; } -inline int regCode(lir::Register* a) +inline int regCode(lir::RegisterPair* a) { return regCode(a->low); } -inline bool isFloatReg(lir::Register* a) +inline bool isFloatReg(lir::RegisterPair* a) { return a->low >= xmm0; } void modrm(Context* c, uint8_t mod, int a, int b); -void modrm(Context* c, uint8_t mod, lir::Register* a, lir::Register* b); +void modrm(Context* c, uint8_t mod, lir::RegisterPair* a, lir::RegisterPair* b); void sib(Context* c, unsigned scale, int index, int base); @@ -67,7 +67,7 @@ void modrmSib(Context* c, int width, int a, int scale, int index, int base); void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset); -void modrmSibImm(Context* c, lir::Register* a, lir::Memory* b); +void modrmSibImm(Context* c, lir::RegisterPair* a, lir::Memory* b); void opcode(Context* c, uint8_t op); @@ -79,25 +79,25 @@ void conditional(Context* c, unsigned condition, lir::Constant* a); void sseMoveRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void sseMoveCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void sseMoveMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void sseMoveRM(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, UNUSED unsigned bSize, lir::Memory* b); @@ -107,9 +107,9 @@ void branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target); void floatRegOp(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b, + lir::RegisterPair* b, uint8_t op, uint8_t mod = 0xc0); @@ -117,14 +117,14 @@ void floatMemOp(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b, + lir::RegisterPair* b, uint8_t op); void moveCR2(Context* c, UNUSED unsigned aSize, lir::Constant* a, UNUSED unsigned bSize, - lir::Register* b, + lir::RegisterPair* b, unsigned promiseOffset); } // namespace x86 diff --git a/src/codegen/target/x86/operations.cpp b/src/codegen/target/x86/operations.cpp index 863d1cf5bf..b9229ea0aa 100644 --- a/src/codegen/target/x86/operations.cpp +++ b/src/codegen/target/x86/operations.cpp @@ -78,7 +78,7 @@ void longCallC(Context* c, unsigned size, lir::Constant* a) assertT(c, size == vm::TargetBytesPerWord); if (vm::TargetBytesPerWord == 8) { - lir::Register r(LongJumpRegister); + lir::RegisterPair r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); callR(c, size, &r); } else { @@ -86,7 +86,7 @@ void longCallC(Context* c, unsigned size, lir::Constant* a) } } -void jumpR(Context* c, unsigned size UNUSED, lir::Register* a) +void jumpR(Context* c, unsigned size UNUSED, lir::RegisterPair* a) { assertT(c, size == vm::TargetBytesPerWord); @@ -115,7 +115,7 @@ void longJumpC(Context* c, unsigned size, lir::Constant* a) assertT(c, size == vm::TargetBytesPerWord); if (vm::TargetBytesPerWord == 8) { - lir::Register r(LongJumpRegister); + lir::RegisterPair r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); jumpR(c, size, &r); } else { @@ -123,7 +123,7 @@ void longJumpC(Context* c, unsigned size, lir::Constant* a) } } -void callR(Context* c, unsigned size UNUSED, lir::Register* a) +void callR(Context* c, unsigned size UNUSED, lir::RegisterPair* a) { assertT(c, size == vm::TargetBytesPerWord); @@ -177,10 +177,10 @@ void alignedLongJumpC(Context* c, unsigned size, lir::Constant* a) } } -void pushR(Context* c, unsigned size, lir::Register* a) +void pushR(Context* c, unsigned size, lir::RegisterPair* a) { if (vm::TargetBytesPerWord == 4 and size == 8) { - lir::Register ah(a->high); + lir::RegisterPair ah(a->high); pushR(c, 4, &ah); pushR(c, 4, a); @@ -190,10 +190,10 @@ void pushR(Context* c, unsigned size, lir::Register* a) } } -void popR(Context* c, unsigned size, lir::Register* a) +void popR(Context* c, unsigned size, lir::RegisterPair* a) { if (vm::TargetBytesPerWord == 4 and size == 8) { - lir::Register ah(a->high); + lir::RegisterPair ah(a->high); popR(c, 4, a); popR(c, 4, &ah); @@ -206,7 +206,7 @@ void popR(Context* c, unsigned size, lir::Register* a) } } -void negateR(Context* c, unsigned size, lir::Register* a) +void negateR(Context* c, unsigned size, lir::RegisterPair* a) { if (vm::TargetBytesPerWord == 4 and size == 8) { assertT(c, a->low == rax and a->high == rdx); @@ -214,7 +214,7 @@ void negateR(Context* c, unsigned size, lir::Register* a) ResolvedPromise zeroPromise(0); lir::Constant zero(&zeroPromise); - lir::Register ah(a->high); + lir::RegisterPair ah(a->high); negateR(c, 4, a); addCarryCR(c, 4, &zero, &ah); @@ -227,9 +227,9 @@ void negateR(Context* c, unsigned size, lir::Register* a) void negateRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b UNUSED) + lir::RegisterPair* b UNUSED) { assertT(c, aSize == bSize); @@ -240,7 +240,7 @@ void moveCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { if (isFloatReg(b)) { sseMoveCR(c, aSize, a, bSize, b); @@ -253,7 +253,7 @@ void moveZCR(Context* c, unsigned aSize UNUSED, lir::Constant* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, not isFloatReg(b)); assertT(c, aSize == 2); @@ -267,9 +267,9 @@ void moveZCR(Context* c, void swapRR(Context* c, unsigned aSize UNUSED, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); assertT(c, aSize == vm::TargetBytesPerWord); @@ -281,9 +281,9 @@ void swapRR(Context* c, void moveRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, UNUSED unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { if (isFloatReg(a) or isFloatReg(b)) { sseMoveRR(c, aSize, a, bSize, b); @@ -291,8 +291,8 @@ void moveRR(Context* c, } if (vm::TargetBytesPerWord == 4 and aSize == 8 and bSize == 8) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); if (a->high == b->low) { if (a->low == b->high) { @@ -366,7 +366,7 @@ void moveMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { if (isFloatReg(b)) { sseMoveMR(c, aSize, a, bSize, b); @@ -408,7 +408,7 @@ void moveMR(Context* c, case 8: if (vm::TargetBytesPerWord == 4 and bSize == 8) { lir::Memory ah(a->base, a->offset + 4, a->index, a->scale); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); moveMR(c, 4, a, 4, b); moveMR(c, 4, &ah, 4, &bh); @@ -426,7 +426,7 @@ void moveMR(Context* c, void moveRM(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, lir::Memory* b) { @@ -469,7 +469,7 @@ void moveRM(Context* c, opcode(c, 0x89); modrmSibImm(c, a, b); } else { - lir::Register ah(a->high); + lir::RegisterPair ah(a->high); lir::Memory bh(b->base, b->offset + 4, b->index, b->scale); moveRM(c, 4, a, 4, b); @@ -486,7 +486,7 @@ void moveAR(Context* c, unsigned aSize, lir::Address* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, vm::TargetBytesPerWord == 8 or (aSize == 4 and bSize == 4)); @@ -539,7 +539,7 @@ void moveCM(Context* c, modrmSibImm(c, 0, b->scale, b->index, b->base, b->offset); c->code.append4(a->value->value()); } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, 8, a, 8, &tmp); moveRM(c, 8, &tmp, 8, b); c->client->releaseTemporary(tmp.low); @@ -562,9 +562,9 @@ void moveCM(Context* c, void moveZRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { switch (aSize) { case 2: @@ -582,7 +582,7 @@ void moveZMR(Context* c, unsigned aSize UNUSED, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, bSize == vm::TargetBytesPerWord); assertT(c, aSize == 2); @@ -592,7 +592,7 @@ void moveZMR(Context* c, modrmSibImm(c, b->low, a->scale, a->index, a->base, a->offset); } -void addCarryRR(Context* c, unsigned size, lir::Register* a, lir::Register* b) +void addCarryRR(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b) { assertT(c, vm::TargetBytesPerWord == 8 or size == 4); @@ -603,15 +603,15 @@ void addCarryRR(Context* c, unsigned size, lir::Register* a, lir::Register* b) void addRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); addRR(c, 4, a, 4, b); addCarryRR(c, 4, &ah, &bh); @@ -622,7 +622,7 @@ void addRR(Context* c, } } -void addCarryCR(Context* c, unsigned size, lir::Constant* a, lir::Register* b) +void addCarryCR(Context* c, unsigned size, lir::Constant* a, lir::RegisterPair* b) { int64_t v = a->value->value(); maybeRex(c, size, b); @@ -639,7 +639,7 @@ void addCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -652,7 +652,7 @@ void addCR(Context* c, ResolvedPromise low(v & 0xFFFFFFFF); lir::Constant al(&low); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); addCR(c, 4, &al, 4, b); addCarryCR(c, 4, &ah, &bh); @@ -667,7 +667,7 @@ void addCR(Context* c, c->code.append4(v); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); addRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -679,7 +679,7 @@ void addCR(Context* c, void subtractBorrowCR(Context* c, unsigned size UNUSED, lir::Constant* a, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, vm::TargetBytesPerWord == 8 or size == 4); @@ -697,7 +697,7 @@ void subtractCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -710,7 +710,7 @@ void subtractCR(Context* c, ResolvedPromise low(v & 0xFFFFFFFF); lir::Constant al(&low); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); subtractCR(c, 4, &al, 4, b); subtractBorrowCR(c, 4, &ah, &bh); @@ -725,7 +725,7 @@ void subtractCR(Context* c, c->code.append4(v); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); subtractRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -736,8 +736,8 @@ void subtractCR(Context* c, void subtractBorrowRR(Context* c, unsigned size, - lir::Register* a, - lir::Register* b) + lir::RegisterPair* a, + lir::RegisterPair* b) { assertT(c, vm::TargetBytesPerWord == 8 or size == 4); @@ -748,15 +748,15 @@ void subtractBorrowRR(Context* c, void subtractRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); subtractRR(c, 4, a, 4, b); subtractBorrowRR(c, 4, &ah, &bh); @@ -769,15 +769,15 @@ void subtractRR(Context* c, void andRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); andRR(c, 4, a, 4, b); andRR(c, 4, &ah, 4, &bh); @@ -792,7 +792,7 @@ void andCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -805,7 +805,7 @@ void andCR(Context* c, ResolvedPromise low(v & 0xFFFFFFFF); lir::Constant al(&low); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); andCR(c, 4, &al, 4, b); andCR(c, 4, &ah, 4, &bh); @@ -820,7 +820,7 @@ void andCR(Context* c, c->code.append4(v); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); andRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -830,15 +830,15 @@ void andCR(Context* c, void orRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); orRR(c, 4, a, 4, b); orRR(c, 4, &ah, 4, &bh); @@ -853,7 +853,7 @@ void orCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -866,7 +866,7 @@ void orCR(Context* c, ResolvedPromise low(v & 0xFFFFFFFF); lir::Constant al(&low); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); orCR(c, 4, &al, 4, b); orCR(c, 4, &ah, 4, &bh); @@ -881,7 +881,7 @@ void orCR(Context* c, c->code.append4(v); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); orRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -892,13 +892,13 @@ void orCR(Context* c, void xorRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { if (vm::TargetBytesPerWord == 4 and aSize == 8) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); xorRR(c, 4, a, 4, b); xorRR(c, 4, &ah, 4, &bh); @@ -913,7 +913,7 @@ void xorCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -926,7 +926,7 @@ void xorCR(Context* c, ResolvedPromise low(v & 0xFFFFFFFF); lir::Constant al(&low); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); xorCR(c, 4, &al, 4, b); xorCR(c, 4, &ah, 4, &bh); @@ -941,7 +941,7 @@ void xorCR(Context* c, c->code.append4(v); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); xorRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -952,9 +952,9 @@ void xorCR(Context* c, void multiplyRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -966,12 +966,12 @@ void multiplyRR(Context* c, c->client->save(rax); - lir::Register axdx(rax, rdx); - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair axdx(rax, rdx); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); - lir::Register tmp(-1); - lir::Register* scratch; + lir::RegisterPair tmp(-1); + lir::RegisterPair* scratch; if (a->low == b->low) { tmp.low = c->client->acquireTemporary(GeneralRegisterMask & ~(1 << rax)); scratch = &tmp; @@ -1003,9 +1003,9 @@ void multiplyRR(Context* c, void compareRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); assertT(c, aSize <= vm::TargetBytesPerWord); @@ -1019,7 +1019,7 @@ void compareCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); assertT(c, vm::TargetBytesPerWord == 8 or aSize == 4); @@ -1035,7 +1035,7 @@ void compareCR(Context* c, c->code.append4(v); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); compareRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -1044,7 +1044,7 @@ void compareCR(Context* c, void compareRM(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, lir::Memory* b) { @@ -1082,7 +1082,7 @@ void compareCM(Context* c, abort(c); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, bSize, &tmp); compareRM(c, bSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -1091,9 +1091,9 @@ void compareCM(Context* c, void compareFloatRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -1192,16 +1192,16 @@ void branchLong(Context* c, void branchRR(Context* c, lir::TernaryOperation op, unsigned size, - lir::Register* a, - lir::Register* b, + lir::RegisterPair* a, + lir::RegisterPair* b, lir::Constant* target) { if (isFloatBranch(op)) { compareFloatRR(c, size, a, size, b); branchFloat(c, op, target); } else if (size > vm::TargetBytesPerWord) { - lir::Register ah(a->high); - lir::Register bh(b->high); + lir::RegisterPair ah(a->high); + lir::RegisterPair bh(b->high); branchLong(c, op, a, &ah, b, &bh, target, CAST2(compareRR)); } else { @@ -1214,7 +1214,7 @@ void branchCR(Context* c, lir::TernaryOperation op, unsigned size, lir::Constant* a, - lir::Register* b, + lir::RegisterPair* b, lir::Constant* target) { assertT(c, not isFloatBranch(op)); @@ -1228,7 +1228,7 @@ void branchCR(Context* c, ResolvedPromise high((v >> 32) & ~static_cast(0)); lir::Constant ah(&high); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); branchLong(c, op, &al, &ah, b, &bh, target, CAST2(compareCR)); } else { @@ -1240,7 +1240,7 @@ void branchCR(Context* c, void branchRM(Context* c, lir::TernaryOperation op, unsigned size, - lir::Register* a, + lir::RegisterPair* a, lir::Memory* b, lir::Constant* target) { @@ -1269,13 +1269,13 @@ void multiplyCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { const RegisterMask mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - lir::Register tmp(c->client->acquireTemporary(mask), + lir::RegisterPair tmp(c->client->acquireTemporary(mask), c->client->acquireTemporary(mask)); moveCR(c, aSize, a, aSize, &tmp); @@ -1297,7 +1297,7 @@ void multiplyCR(Context* c, c->code.append4(v); } } else { - lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); multiplyRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -1308,9 +1308,9 @@ void multiplyCR(Context* c, void divideRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b UNUSED) + lir::RegisterPair* b UNUSED) { assertT(c, aSize == bSize); @@ -1327,9 +1327,9 @@ void divideRR(Context* c, void remainderRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -1343,28 +1343,28 @@ void remainderRR(Context* c, maybeRex(c, aSize, b, a); opcode(c, 0xf7, 0xf8 + regCode(a)); - lir::Register dx(rdx); + lir::RegisterPair dx(rdx); moveRR(c, vm::TargetBytesPerWord, &dx, vm::TargetBytesPerWord, b); } void doShift(Context* c, UNUSED void (*shift)(Context*, unsigned, - lir::Register*, + lir::RegisterPair*, unsigned, - lir::Register*), + lir::RegisterPair*), int type, UNUSED unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { int64_t v = a->value->value(); if (vm::TargetBytesPerWord == 4 and bSize == 8) { c->client->save(rcx); - lir::Register cx(rcx); + lir::RegisterPair cx(rcx); ResolvedPromise promise(v & 0x3F); lir::Constant masked(&promise); moveCR(c, 4, &masked, 4, &cx); @@ -1384,12 +1384,12 @@ void doShift(Context* c, void shiftLeftRR(Context* c, UNUSED unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { if (vm::TargetBytesPerWord == 4 and bSize == 8) { - lir::Register cx(rcx); + lir::RegisterPair cx(rcx); if (a->low != rcx) { c->client->save(rcx); ResolvedPromise promise(0x3F); @@ -1413,7 +1413,7 @@ void shiftLeftRR(Context* c, opcode(c, 0x7c); // jl c->code.append(2 + 2); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); moveRR(c, 4, b, 4, &bh); // 2 bytes xorRR(c, 4, b, 4, b); // 2 bytes } else { @@ -1428,19 +1428,19 @@ void shiftLeftCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { doShift(c, shiftLeftRR, 0xe0, aSize, a, bSize, b); } void shiftRightRR(Context* c, UNUSED unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { if (vm::TargetBytesPerWord == 4 and bSize == 8) { - lir::Register cx(rcx); + lir::RegisterPair cx(rcx); if (a->low != rcx) { c->client->save(rcx); ResolvedPromise promise(0x3F); @@ -1464,7 +1464,7 @@ void shiftRightRR(Context* c, opcode(c, 0x7c); // jl c->code.append(2 + 3); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); moveRR(c, 4, &bh, 4, b); // 2 bytes // sar 31,high @@ -1482,19 +1482,19 @@ void shiftRightCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { doShift(c, shiftRightRR, 0xf8, aSize, a, bSize, b); } void unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { if (vm::TargetBytesPerWord == 4 and bSize == 8) { - lir::Register cx(rcx); + lir::RegisterPair cx(rcx); if (a->low != rcx) { c->client->save(rcx); ResolvedPromise promise(0x3F); @@ -1518,7 +1518,7 @@ void unsignedShiftRightRR(Context* c, opcode(c, 0x7c); // jl c->code.append(2 + 2); - lir::Register bh(b->high); + lir::RegisterPair bh(b->high); moveRR(c, 4, &bh, 4, b); // 2 bytes xorRR(c, 4, &bh, 4, &bh); // 2 bytes } else { @@ -1533,16 +1533,16 @@ void unsignedShiftRightCR(Context* c, unsigned aSize UNUSED, lir::Constant* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { doShift(c, unsignedShiftRightRR, 0xe8, aSize, a, bSize, b); } void floatSqrtRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatRegOp(c, aSize, a, 4, b, 0x51); } @@ -1551,16 +1551,16 @@ void floatSqrtMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, aSize, a, 4, b, 0x51); } void floatAddRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatRegOp(c, aSize, a, 4, b, 0x58); } @@ -1569,16 +1569,16 @@ void floatAddMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, aSize, a, 4, b, 0x58); } void floatSubtractRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatRegOp(c, aSize, a, 4, b, 0x5c); } @@ -1587,16 +1587,16 @@ void floatSubtractMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, aSize, a, 4, b, 0x5c); } void floatMultiplyRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatRegOp(c, aSize, a, 4, b, 0x59); } @@ -1605,16 +1605,16 @@ void floatMultiplyMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, aSize, a, 4, b, 0x59); } void floatDivideRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatRegOp(c, aSize, a, 4, b, 0x5e); } @@ -1623,16 +1623,16 @@ void floatDivideMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, aSize, a, 4, b, 0x5e); } void float2FloatRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatRegOp(c, aSize, a, 4, b, 0x5a); } @@ -1641,16 +1641,16 @@ void float2FloatMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, aSize, a, 4, b, 0x5a); } void float2IntRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, not isFloatReg(b)); floatRegOp(c, aSize, a, bSize, b, 0x2c); @@ -1660,16 +1660,16 @@ void float2IntMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, aSize, a, bSize, b, 0x2c); } void int2FloatRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { floatRegOp(c, bSize, a, aSize, b, 0x2a); } @@ -1678,16 +1678,16 @@ void int2FloatMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b) + lir::RegisterPair* b) { floatMemOp(c, bSize, a, aSize, b, 0x2a); } void floatNegateRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, isFloatReg(a) and isFloatReg(b)); // unlike most of the other floating point code, this does NOT @@ -1696,7 +1696,7 @@ void floatNegateRR(Context* c, ResolvedPromise pcon(0x80000000); lir::Constant con(&pcon); if (a->low == b->low) { - lir::Register tmp(c->client->acquireTemporary(FloatRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(FloatRegisterMask)); moveCR(c, 4, &con, 4, &tmp); maybeRex(c, 4, a, &tmp); opcode(c, 0x0f, 0x57); @@ -1714,9 +1714,9 @@ void floatNegateRR(Context* c, void floatAbsoluteRR(Context* c, unsigned aSize UNUSED, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b) + lir::RegisterPair* b) { assertT(c, isFloatReg(a) and isFloatReg(b)); // unlike most of the other floating point code, this does NOT @@ -1725,7 +1725,7 @@ void floatAbsoluteRR(Context* c, ResolvedPromise pcon(0x7fffffff); lir::Constant con(&pcon); if (a->low == b->low) { - lir::Register tmp(c->client->acquireTemporary(FloatRegisterMask)); + lir::RegisterPair tmp(c->client->acquireTemporary(FloatRegisterMask)); moveCR(c, 4, &con, 4, &tmp); maybeRex(c, 4, a, &tmp); opcode(c, 0x0f, 0x54); @@ -1741,12 +1741,12 @@ void floatAbsoluteRR(Context* c, void absoluteRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b UNUSED) + lir::RegisterPair* b UNUSED) { assertT(c, aSize == bSize and a->low == rax and b->low == rax); - lir::Register d(c->client->acquireTemporary(static_cast(1) << rdx)); + lir::RegisterPair d(c->client->acquireTemporary(static_cast(1) << rdx)); maybeRex(c, aSize, a, b); opcode(c, 0x99); xorRR(c, aSize, &d, aSize, a); diff --git a/src/codegen/target/x86/operations.h b/src/codegen/target/x86/operations.h index 80f985f042..1b322788e8 100644 --- a/src/codegen/target/x86/operations.h +++ b/src/codegen/target/x86/operations.h @@ -33,7 +33,7 @@ void callC(Context* c, unsigned size UNUSED, lir::Constant* a); void longCallC(Context* c, unsigned size, lir::Constant* a); -void jumpR(Context* c, unsigned size UNUSED, lir::Register* a); +void jumpR(Context* c, unsigned size UNUSED, lir::RegisterPair* a); void jumpC(Context* c, unsigned size UNUSED, lir::Constant* a); @@ -41,7 +41,7 @@ void jumpM(Context* c, unsigned size UNUSED, lir::Memory* a); void longJumpC(Context* c, unsigned size, lir::Constant* a); -void callR(Context* c, unsigned size UNUSED, lir::Register* a); +void callR(Context* c, unsigned size UNUSED, lir::RegisterPair* a); void callM(Context* c, unsigned size UNUSED, lir::Memory* a); @@ -53,51 +53,51 @@ void alignedJumpC(Context* c, unsigned size, lir::Constant* a); void alignedLongJumpC(Context* c, unsigned size, lir::Constant* a); -void pushR(Context* c, unsigned size, lir::Register* a); +void pushR(Context* c, unsigned size, lir::RegisterPair* a); -void popR(Context* c, unsigned size, lir::Register* a); +void popR(Context* c, unsigned size, lir::RegisterPair* a); -void negateR(Context* c, unsigned size, lir::Register* a); +void negateR(Context* c, unsigned size, lir::RegisterPair* a); void negateRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b UNUSED); + lir::RegisterPair* b UNUSED); void moveCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void moveZCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void swapRR(Context* c, unsigned aSize UNUSED, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void moveRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, UNUSED unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void moveMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void moveRM(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, lir::Memory* b); @@ -105,7 +105,7 @@ void moveAR(Context* c, unsigned aSize, lir::Address* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void moveCM(Context* c, unsigned aSize UNUSED, @@ -115,111 +115,111 @@ void moveCM(Context* c, void moveZRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void moveZMR(Context* c, unsigned aSize UNUSED, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); -void addCarryRR(Context* c, unsigned size, lir::Register* a, lir::Register* b); +void addCarryRR(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b); void addRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); -void addCarryCR(Context* c, unsigned size, lir::Constant* a, lir::Register* b); +void addCarryCR(Context* c, unsigned size, lir::Constant* a, lir::RegisterPair* b); void addCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void subtractBorrowCR(Context* c, unsigned size UNUSED, lir::Constant* a, - lir::Register* b); + lir::RegisterPair* b); void subtractCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void subtractBorrowRR(Context* c, unsigned size, - lir::Register* a, - lir::Register* b); + lir::RegisterPair* a, + lir::RegisterPair* b); void subtractRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void andRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void andCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void orRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void orCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void xorRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void xorCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void multiplyRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void compareRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void compareCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void compareRM(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, lir::Memory* b); @@ -231,9 +231,9 @@ void compareCM(Context* c, void compareFloatRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void branchLong(Context* c, lir::TernaryOperation op, @@ -247,21 +247,21 @@ void branchLong(Context* c, void branchRR(Context* c, lir::TernaryOperation op, unsigned size, - lir::Register* a, - lir::Register* b, + lir::RegisterPair* a, + lir::RegisterPair* b, lir::Constant* target); void branchCR(Context* c, lir::TernaryOperation op, unsigned size, lir::Constant* a, - lir::Register* b, + lir::RegisterPair* b, lir::Constant* target); void branchRM(Context* c, lir::TernaryOperation op, unsigned size, - lir::Register* a, + lir::RegisterPair* a, lir::Memory* b, lir::Constant* target); @@ -276,181 +276,181 @@ void multiplyCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void divideRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b UNUSED); + lir::RegisterPair* b UNUSED); void remainderRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void doShift(Context* c, UNUSED void (*shift)(Context*, unsigned, - lir::Register*, + lir::RegisterPair*, unsigned, - lir::Register*), + lir::RegisterPair*), int type, UNUSED unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void shiftLeftRR(Context* c, UNUSED unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void shiftLeftCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void shiftRightRR(Context* c, UNUSED unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void shiftRightCR(Context* c, unsigned aSize, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void unsignedShiftRightCR(Context* c, unsigned aSize UNUSED, lir::Constant* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void floatSqrtRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatSqrtMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatAddRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatAddMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatSubtractRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatSubtractMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatMultiplyRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatMultiplyMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatDivideRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatDivideMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void float2FloatRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void float2FloatMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void float2IntRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void float2IntMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void int2FloatRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void int2FloatMR(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, - lir::Register* b); + lir::RegisterPair* b); void floatNegateRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void floatAbsoluteRR(Context* c, unsigned aSize UNUSED, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b); + lir::RegisterPair* b); void absoluteRR(Context* c, unsigned aSize, - lir::Register* a, + lir::RegisterPair* a, unsigned bSize UNUSED, - lir::Register* b UNUSED); + lir::RegisterPair* b UNUSED); } // namespace x86 } // namespace codegen diff --git a/src/compile.cpp b/src/compile.cpp index a3f6e47cae..47b55574e7 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -9783,7 +9783,7 @@ void compileCall(MyThread* t, Context* c, ThunkIndex index, bool call = true) if (processor(t)->bootImage) { lir::Memory table(t->arch->thread(), TARGET_THREAD_THUNKTABLE); - lir::Register scratch(t->arch->scratch()); + lir::RegisterPair scratch(t->arch->scratch()); a->apply(lir::Move, OperandInfo(TargetBytesPerWord, lir::Operand::Type::Memory, &table), OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &scratch)); @@ -9814,14 +9814,14 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.default_.frameSavedOffset = a->length(); - lir::Register thread(t->arch->thread()); + lir::RegisterPair thread(t->arch->thread()); a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, compileMethodIndex); a->popFrame(t->arch->alignFrameSize(1)); - lir::Register result(t->arch->returnLow()); + lir::RegisterPair result(t->arch->returnLow()); a->apply(lir::Jump, OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &result)); @@ -9835,7 +9835,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) Context context(t); avian::codegen::Assembler* a = context.assembler; - lir::Register class_(t->arch->virtualCallTarget()); + lir::RegisterPair class_(t->arch->virtualCallTarget()); lir::Memory virtualCallTargetSrc( t->arch->stack(), (t->arch->frameFooterSize() + t->arch->frameReturnAddressSize()) @@ -9855,7 +9855,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) OperandInfo( TargetBytesPerWord, lir::Operand::Type::Memory, &virtualCallTargetDst)); - lir::Register index(t->arch->virtualCallIndex()); + lir::RegisterPair index(t->arch->virtualCallIndex()); lir::Memory virtualCallIndex(t->arch->thread(), TARGET_THREAD_VIRTUALCALLINDEX); @@ -9868,14 +9868,14 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.defaultVirtual.frameSavedOffset = a->length(); - lir::Register thread(t->arch->thread()); + lir::RegisterPair thread(t->arch->thread()); a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, compileVirtualMethodIndex); a->popFrame(t->arch->alignFrameSize(1)); - lir::Register result(t->arch->returnLow()); + lir::RegisterPair result(t->arch->returnLow()); a->apply(lir::Jump, OperandInfo(TargetBytesPerWord, lir::Operand::Type::RegisterPair, &result)); @@ -9893,7 +9893,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.native.frameSavedOffset = a->length(); - lir::Register thread(t->arch->thread()); + lir::RegisterPair thread(t->arch->thread()); a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, invokeNativeIndex); @@ -9915,7 +9915,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.aioob.frameSavedOffset = a->length(); - lir::Register thread(t->arch->thread()); + lir::RegisterPair thread(t->arch->thread()); a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, throwArrayIndexOutOfBoundsIndex); @@ -9934,7 +9934,7 @@ void compileThunks(MyThread* t, FixedAllocator* allocator) p->thunks.stackOverflow.frameSavedOffset = a->length(); - lir::Register thread(t->arch->thread()); + lir::RegisterPair thread(t->arch->thread()); a->pushFrame(1, TargetBytesPerWord, lir::Operand::Type::RegisterPair, &thread); compileCall(t, &context, throwStackOverflowIndex); @@ -10058,7 +10058,7 @@ uintptr_t compileVirtualThunk(MyThread* t, unsigned index, unsigned* size) avian::codegen::ResolvedPromise indexPromise(index); lir::Constant indexConstant(&indexPromise); - lir::Register indexRegister(t->arch->virtualCallIndex()); + lir::RegisterPair indexRegister(t->arch->virtualCallIndex()); a->apply( lir::Move, OperandInfo(TargetBytesPerWord, lir::Operand::Type::Constant, &indexConstant), From 998a5168b7268fdcb2b66eff066a0b7b6f58bf7a Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 19:07:45 -0700 Subject: [PATCH 18/70] make Register a class --- include/avian/codegen/architecture.h | 16 +- include/avian/codegen/assembler.h | 4 +- include/avian/codegen/lir.h | 14 +- include/avian/codegen/registers.h | 32 ++- src/codegen/compiler.cpp | 6 +- src/codegen/compiler/event.cpp | 24 +- src/codegen/compiler/regalloc.cpp | 16 +- src/codegen/compiler/regalloc.h | 13 +- src/codegen/compiler/site.cpp | 110 ++++----- src/codegen/compiler/site.h | 24 +- src/codegen/registers.cpp | 2 + src/codegen/target/arm/assembler.cpp | 28 +-- src/codegen/target/arm/encode.h | 318 +++++++++++++------------- src/codegen/target/arm/operations.cpp | 50 ++-- src/codegen/target/arm/operations.h | 4 +- src/codegen/target/arm/registers.h | 8 +- src/codegen/target/x86/assembler.cpp | 30 +-- src/codegen/target/x86/encode.cpp | 32 +-- src/codegen/target/x86/encode.h | 14 +- src/codegen/target/x86/operations.cpp | 14 +- unittest/codegen/registers-test.cpp | 8 +- 21 files changed, 401 insertions(+), 366 deletions(-) diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index 193311b876..5500311446 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -61,13 +61,13 @@ class Architecture { virtual const RegisterFile* registerFile() = 0; - virtual int scratch() = 0; - virtual int stack() = 0; - virtual int thread() = 0; - virtual int returnLow() = 0; - virtual int returnHigh() = 0; - virtual int virtualCallTarget() = 0; - virtual int virtualCallIndex() = 0; + virtual Register scratch() = 0; + virtual Register stack() = 0; + virtual Register thread() = 0; + virtual Register returnLow() = 0; + virtual Register returnHigh() = 0; + virtual Register virtualCallTarget() = 0; + virtual Register virtualCallIndex() = 0; virtual ir::TargetInfo targetInfo() = 0; @@ -78,7 +78,7 @@ class Architecture { virtual bool alwaysCondensed(lir::BinaryOperation op) = 0; virtual bool alwaysCondensed(lir::TernaryOperation op) = 0; - virtual bool reserved(int register_) = 0; + virtual bool reserved(Register register_) = 0; virtual unsigned frameFootprint(unsigned footprint) = 0; virtual unsigned argumentFootprint(unsigned footprint) = 0; diff --git a/include/avian/codegen/assembler.h b/include/avian/codegen/assembler.h index 25707f4853..d7be61c326 100644 --- a/include/avian/codegen/assembler.h +++ b/include/avian/codegen/assembler.h @@ -77,8 +77,8 @@ class Assembler { virtual void popFrame(unsigned footprint) = 0; virtual void popFrameForTailCall(unsigned footprint, int offset, - int returnAddressSurrogate, - int framePointerSurrogate) = 0; + Register returnAddressSurrogate, + Register framePointerSurrogate) = 0; virtual void popFrameAndPopArgumentsAndReturn(unsigned frameFootprint, unsigned argumentFootprint) = 0; virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint, diff --git a/include/avian/codegen/lir.h b/include/avian/codegen/lir.h index b5f9efe259..66289a616e 100644 --- a/include/avian/codegen/lir.h +++ b/include/avian/codegen/lir.h @@ -11,6 +11,8 @@ #ifndef AVIAN_CODEGEN_LIR_H #define AVIAN_CODEGEN_LIR_H +#include + namespace avian { namespace codegen { class Promise; @@ -151,24 +153,24 @@ class Address : public Operand { class RegisterPair : public Operand { public: - RegisterPair(int low, int high = NoRegister) : low(low), high(high) + RegisterPair(Register low, Register high = NoRegister) : low(low), high(high) { } - int low; - int high; + Register low; + Register high; }; class Memory : public Operand { public: - Memory(int base, int offset, int index = NoRegister, unsigned scale = 1) + Memory(Register base, int offset, Register index = NoRegister, unsigned scale = 1) : base(base), offset(offset), index(index), scale(scale) { } - int base; + Register base; int offset; - int index; + Register index; unsigned scale; }; diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 57406d9a91..404e65fd46 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -16,7 +16,27 @@ namespace avian { namespace codegen { -typedef int Register; +class Register { +private: + int8_t index; +public: + Register(int8_t index) : index(index) {} + Register() : index(0xff) {} + + bool operator == (Register o) const { + return index == o.index; + } + + bool operator != (Register o) const { + return !(*this == o); + } + + explicit operator int8_t() const { + return index; + } + + static Register None; +}; class RegisterMask { private: @@ -24,6 +44,7 @@ private: public: RegisterMask(uint64_t mask) : mask(mask) {} RegisterMask() : mask(0) {} + RegisterMask(Register reg) : mask(static_cast(1) << (int8_t)reg) {} RegisterMask operator &(RegisterMask o) const { return RegisterMask(mask & o.mask); @@ -39,11 +60,15 @@ public: } bool contains(Register reg) const { - return (mask & (static_cast(1) << reg)) != 0; + return (mask & (static_cast(1) << (int8_t)reg)) != 0; } bool containsExactly(Register reg) const { - return mask == (mask & (static_cast(1) << reg)); + return mask == (mask & (static_cast(1) << (int8_t)reg)); + } + + RegisterMask excluding(Register reg) const { + return RegisterMask(mask & ~(static_cast(1) << (int8_t)reg)); } explicit operator uint64_t() const { @@ -55,6 +80,7 @@ public: } static RegisterMask Any; + static RegisterMask None; }; class BoundedRegisterMask { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 1e367497d5..5687d5b3c3 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -2216,18 +2216,18 @@ class Client : public Assembler::Client { Register r = pickRegisterTarget(c, 0, mask, &cost); expect(c, cost < Target::Impossible); save(r); - c->registerResources[r].increment(c); + c->registerResources[(int8_t)r].increment(c); return r; } virtual void releaseTemporary(Register r) { - c->registerResources[r].decrement(c); + c->registerResources[(int8_t)r].decrement(c); } virtual void save(Register r) { - RegisterResource* reg = c->registerResources + r; + RegisterResource* reg = c->registerResources + (int8_t)r; assertT(c, reg->referenceCount == 0); assertT(c, reg->freezeCount == 0); diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index d5b6a67dcf..73c612a378 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -399,11 +399,11 @@ class CallEvent : public Event { Register number = c->arch->argumentRegister(index); if (DebugReads) { - fprintf(stderr, "reg %d arg read %p\n", number, v); + fprintf(stderr, "reg %d arg read %p\n", (int8_t)number, v); } targetMask = SiteMask::fixedRegisterMask(number); - registerMask &= ~(1 << number); + registerMask = registerMask.excluding(number); } else { if (index < c->arch->argumentRegisterCount()) { index = c->arch->argumentRegisterCount(); @@ -587,23 +587,23 @@ class CallEvent : public Event { framePointerSurrogate == 0 or framePointerSurrogate->source->type(c) == lir::Operand::Type::RegisterPair); - int ras; + Register ras; if (returnAddressSurrogate) { returnAddressSurrogate->source->freeze(c, returnAddressSurrogate); ras = static_cast(returnAddressSurrogate->source) ->number; } else { - ras = lir::NoRegister; + ras = Register::None; } - int fps; + Register fps; if (framePointerSurrogate) { framePointerSurrogate->source->freeze(c, framePointerSurrogate); fps = static_cast(framePointerSurrogate->source)->number; } else { - fps = lir::NoRegister; + fps = Register::None; } int offset = static_cast(footprint) @@ -1498,14 +1498,14 @@ class MemoryEvent : public Event { virtual void compile(Context* c) { - int indexRegister; + Register indexRegister; int displacement = this->displacement; unsigned scale = this->scale; if (index) { ConstantSite* constant = findConstantSite(c, index); if (constant) { - indexRegister = lir::NoRegister; + indexRegister = Register::None; displacement += (constant->value->value() * scale); scale = 1; } else { @@ -1513,14 +1513,14 @@ class MemoryEvent : public Event { indexRegister = static_cast(index->source)->number; } } else { - indexRegister = lir::NoRegister; + indexRegister = Register::None; } assertT(c, base->source->type(c) == lir::Operand::Type::RegisterPair); - int baseRegister = static_cast(base->source)->number; + Register baseRegister = static_cast(base->source)->number; popRead(c, this, base); if (index) { - if (c->targetInfo.pointerSize == 8 and indexRegister != lir::NoRegister) { + if (c->targetInfo.pointerSize == 8 and indexRegister != Register::None) { apply(c, lir::Move, 4, @@ -2035,7 +2035,7 @@ class BoundsCheckEvent : public Event { assertT(c, object->source->type(c) == lir::Operand::Type::RegisterPair); MemorySite length(static_cast(object->source)->number, lengthOffset, - lir::NoRegister, + Register::None, 1); length.acquired = true; diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 0c60ae0d0d..844eae6b70 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -65,13 +65,13 @@ bool pickRegisterTarget(Context* c, CostCalculator* costCalculator) { if (mask.contains(i)) { - RegisterResource* r = c->registerResources + i; + RegisterResource* r = c->registerResources + (int8_t)i; unsigned myCost = resourceCost( c, v, r, - SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << i, NoFrameIndex), + SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, RegisterMask(i), NoFrameIndex), costCalculator) + Target::MinimumRegisterCost; if (mask.containsExactly(i)) { @@ -91,13 +91,13 @@ Register pickRegisterTarget(Context* c, unsigned* cost, CostCalculator* costCalculator) { - Register target = lir::NoRegister; + Register target = Register::None; *cost = Target::Impossible; if (mask & c->regFile->generalRegisters.mask) { for (Register i = c->regFile->generalRegisters.limit - 1; - i >= c->regFile->generalRegisters.start; - --i) { + (int8_t)i >= c->regFile->generalRegisters.start; + i = (int8_t)i - 1) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } @@ -106,8 +106,8 @@ Register pickRegisterTarget(Context* c, if (mask & c->regFile->floatRegisters.mask) { for (Register i = c->regFile->floatRegisters.start; - i < static_cast(c->regFile->floatRegisters.limit); - ++i) { + (int8_t)i < c->regFile->floatRegisters.limit; + i = (int8_t)i + 1) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } @@ -124,7 +124,7 @@ Target pickRegisterTarget(Context* c, { unsigned cost; Register number = pickRegisterTarget(c, v, mask, &cost, costCalculator); - return Target(number, lir::Operand::Type::RegisterPair, cost); + return Target(number, cost); } unsigned frameCost(Context* c, diff --git a/src/codegen/compiler/regalloc.h b/src/codegen/compiler/regalloc.h index 0dab9d1e3d..c10105fb9d 100644 --- a/src/codegen/compiler/regalloc.h +++ b/src/codegen/compiler/regalloc.h @@ -55,11 +55,16 @@ class Target { { } - Target(Register index, lir::Operand::Type type, unsigned cost) + Target(int16_t index, lir::Operand::Type type, unsigned cost) : index(index), type(type), cost(cost) { } + Target(Register reg, unsigned cost) + : index((int8_t)reg), type(lir::Operand::Type::RegisterPair), cost(cost) + { + } + int16_t index; lir::Operand::Type type; uint8_t cost; @@ -77,14 +82,14 @@ unsigned resourceCost(Context* c, CostCalculator* costCalculator); bool pickRegisterTarget(Context* c, - int i, + Register i, Value* v, RegisterMask mask, - int* target, + Register* target, unsigned* cost, CostCalculator* costCalculator = 0); -int pickRegisterTarget(Context* c, +Register pickRegisterTarget(Context* c, Value* v, RegisterMask mask, unsigned* cost, diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 1b7880d2d0..25810e8773 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -217,14 +217,14 @@ Site* addressSite(Context* c, Promise* address) return new (c->zone) AddressSite(address); } -RegisterSite::RegisterSite(RegisterMask mask, int number) +RegisterSite::RegisterSite(RegisterMask mask, Register number) : mask_(mask), number(number) { } unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize) { - if (number != lir::NoRegister) { + if (number != Register::None) { return vm::snprintf(buffer, bufferSize, "%p register %d", this, number); } else { return vm::snprintf( @@ -234,7 +234,7 @@ unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize) unsigned RegisterSite::copyCost(Context* c, Site* s) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); if (s and (this == s or (s->type(c) == lir::Operand::Type::RegisterPair @@ -247,7 +247,7 @@ unsigned RegisterSite::copyCost(Context* c, Site* s) bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { return mask.registerMask.contains(number); @@ -258,7 +258,7 @@ bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { return mask.registerMask.containsExactly(number); @@ -269,7 +269,7 @@ bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); if (s->type(c) != lir::Operand::Type::RegisterPair) { return false; @@ -278,7 +278,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) RegisterSite* rs = static_cast(s); unsigned size = rs->registerSize(c); if (size > c->targetInfo.pointerSize) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); return number == rs->number; } else { RegisterMask mask = c->regFile->generalRegisters.mask; @@ -289,8 +289,8 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) void RegisterSite::acquire(Context* c, Value* v) { Target target; - if (number != lir::NoRegister) { - target = Target(number, lir::Operand::Type::RegisterPair, 0); + if (number != Register::None) { + target = Target(number, 0); } else { target = pickRegisterTarget(c, v, mask_); expect(c, target.cost < Target::Impossible); @@ -304,30 +304,30 @@ void RegisterSite::acquire(Context* c, Value* v) void RegisterSite::release(Context* c, Value* v) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); - compiler::release(c, c->registerResources + number, v, this); + compiler::release(c, c->registerResources + (int8_t)number, v, this); } void RegisterSite::freeze(Context* c, Value* v) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); - c->registerResources[number].freeze(c, v); + c->registerResources[(int8_t)number].freeze(c, v); } void RegisterSite::thaw(Context* c, Value* v) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); - c->registerResources[number].thaw(c, v); + c->registerResources[(int8_t)number].thaw(c, v); } bool RegisterSite::frozen(Context* c UNUSED) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); - return c->registerResources[number].freezeCount != 0; + return c->registerResources[(int8_t)number].freezeCount != 0; } lir::Operand::Type RegisterSite::type(Context*) @@ -339,14 +339,14 @@ void RegisterSite::asAssemblerOperand(Context* c UNUSED, Site* high, lir::Operand* result) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); - int highNumber; + Register highNumber; if (high != this) { highNumber = static_cast(high)->number; - assertT(c, highNumber != lir::NoRegister); + assertT(c, highNumber != Register::None); } else { - highNumber = lir::NoRegister; + highNumber = Register::None; } new (result) lir::RegisterPair(number, highNumber); @@ -356,8 +356,8 @@ Site* RegisterSite::copy(Context* c) { RegisterMask mask; - if (number != lir::NoRegister) { - mask = 1 << number; + if (number != Register::None) { + mask = RegisterMask(number); } else { mask = mask_; } @@ -377,7 +377,7 @@ Site* RegisterSite::copyHigh(Context* c) Site* RegisterSite::makeNextWord(Context* c, unsigned) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); assertT(c, c->regFile->generalRegisters.mask.contains(number)); return freeRegisterSite(c, c->regFile->generalRegisters.mask); @@ -390,7 +390,7 @@ SiteMask RegisterSite::mask(Context* c UNUSED) SiteMask RegisterSite::nextWordMask(Context* c, unsigned) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); if (registerSize(c) > c->targetInfo.pointerSize) { return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, number, NoFrameIndex); @@ -403,7 +403,7 @@ SiteMask RegisterSite::nextWordMask(Context* c, unsigned) unsigned RegisterSite::registerSize(Context* c) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); if (c->regFile->floatRegisters.mask.contains(number)) { return c->arch->floatRegisterSize(); @@ -412,29 +412,29 @@ unsigned RegisterSite::registerSize(Context* c) } } -unsigned RegisterSite::registerMask(Context* c UNUSED) +RegisterMask RegisterSite::registerMask(Context* c UNUSED) { - assertT(c, number != lir::NoRegister); + assertT(c, number != Register::None); - return 1 << number; + return RegisterMask(number); } -Site* registerSite(Context* c, int number) +Site* registerSite(Context* c, Register number) { - assertT(c, number >= 0); + assertT(c, number != Register::None); assertT(c, (c->regFile->generalRegisters.mask | c->regFile->floatRegisters.mask).contains(number)); - return new (c->zone) RegisterSite(1 << number, number); + return new (c->zone) RegisterSite(RegisterMask(number), number); } Site* freeRegisterSite(Context* c, RegisterMask mask) { - return new (c->zone) RegisterSite(mask, lir::NoRegister); + return new (c->zone) RegisterSite(mask, Register::None); } -MemorySite::MemorySite(int base, int offset, int index, unsigned scale) +MemorySite::MemorySite(Register base, int offset, Register index, unsigned scale) : acquired(false), base(base), offset(offset), index(index), scale(scale) { } @@ -468,7 +468,7 @@ bool MemorySite::conflicts(const SiteMask& mask) { return (mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) != 0 and (!mask.registerMask.contains(base) - or (index != lir::NoRegister + or (index != Register::None and !mask.registerMask.contains(index))); } @@ -479,7 +479,7 @@ bool MemorySite::match(Context* c, const SiteMask& mask) if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { if (mask.frameIndex >= 0) { if (base == c->arch->stack()) { - assertT(c, index == lir::NoRegister); + assertT(c, index == Register::None); return static_cast(frameIndexToOffset(c, mask.frameIndex)) == offset; } else { @@ -499,7 +499,7 @@ bool MemorySite::loneMatch(Context* c, const SiteMask& mask) if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { if (base == c->arch->stack()) { - assertT(c, index == lir::NoRegister); + assertT(c, index == Register::None); if (mask.frameIndex == AnyFrameIndex) { return false; @@ -532,13 +532,13 @@ bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) void MemorySite::acquire(Context* c, Value* v) { - c->registerResources[base].increment(c); - if (index != lir::NoRegister) { - c->registerResources[index].increment(c); + c->registerResources[(int8_t)base].increment(c); + if (index != Register::None) { + c->registerResources[(int8_t)index].increment(c); } if (base == c->arch->stack()) { - assertT(c, index == lir::NoRegister); + assertT(c, index == Register::None); assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); compiler::acquire( @@ -551,16 +551,16 @@ void MemorySite::acquire(Context* c, Value* v) void MemorySite::release(Context* c, Value* v) { if (base == c->arch->stack()) { - assertT(c, index == lir::NoRegister); + assertT(c, index == Register::None); assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); compiler::release( c, c->frameResources + offsetToFrameIndex(c, offset), v, this); } - c->registerResources[base].decrement(c); - if (index != lir::NoRegister) { - c->registerResources[index].decrement(c); + c->registerResources[(int8_t)base].decrement(c); + if (index != Register::None) { + c->registerResources[(int8_t)index].decrement(c); } acquired = false; @@ -571,9 +571,9 @@ void MemorySite::freeze(Context* c, Value* v) if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); } else { - c->registerResources[base].increment(c); - if (index != lir::NoRegister) { - c->registerResources[index].increment(c); + c->registerResources[(int8_t)base].increment(c); + if (index != Register::None) { + c->registerResources[(int8_t)index].increment(c); } } } @@ -583,9 +583,9 @@ void MemorySite::thaw(Context* c, Value* v) if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); } else { - c->registerResources[base].decrement(c); - if (index != lir::NoRegister) { - c->registerResources[index].decrement(c); + c->registerResources[(int8_t)base].decrement(c); + if (index != Register::None) { + c->registerResources[(int8_t)index].decrement(c); } } } @@ -668,7 +668,7 @@ SiteMask MemorySite::nextWordMask(Context* c, unsigned index) { int frameIndex; if (base == c->arch->stack()) { - assertT(c, this->index == lir::NoRegister); + assertT(c, this->index == Register::None); frameIndex = static_cast(offsetToFrameIndex(c, offset)) + ((index == 1) xor c->arch->bigEndian() ? 1 : -1); } else { @@ -683,9 +683,9 @@ bool MemorySite::isVolatile(Context* c) } MemorySite* memorySite(Context* c, - int base, + Register base, int offset, - int index, + Register index, unsigned scale) { return new (c->zone) MemorySite(base, offset, index, scale); @@ -697,7 +697,7 @@ MemorySite* frameSite(Context* c, int frameIndex) return memorySite(c, c->arch->stack(), frameIndexToOffset(c, frameIndex), - lir::NoRegister, + Register::None, 0); } diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 6344936e0c..64da8cd71a 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -41,9 +41,9 @@ class SiteMask { SiteMask intersectionWith(const SiteMask& b); - static SiteMask fixedRegisterMask(int number) + static SiteMask fixedRegisterMask(Register number) { - return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << number, NoFrameIndex); + return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << (int8_t)number, NoFrameIndex); } static SiteMask lowPart(const OperandMask& mask) @@ -121,7 +121,7 @@ class Site { virtual unsigned registerSize(Context*); - virtual unsigned registerMask(Context*) + virtual RegisterMask registerMask(Context*) { return 0; } @@ -251,7 +251,7 @@ Site* addressSite(Context* c, Promise* address); class RegisterSite : public Site { public: - RegisterSite(RegisterMask mask, int number); + RegisterSite(RegisterMask mask, Register number); virtual unsigned toString(Context*, char* buffer, unsigned bufferSize); @@ -293,18 +293,18 @@ class RegisterSite : public Site { virtual unsigned registerSize(Context* c); - virtual unsigned registerMask(Context* c UNUSED); + virtual RegisterMask registerMask(Context* c UNUSED); RegisterMask mask_; - int number; + Register number; }; -Site* registerSite(Context* c, int number); +Site* registerSite(Context* c, Register number); Site* freeRegisterSite(Context* c, RegisterMask mask); class MemorySite : public Site { public: - MemorySite(int base, int offset, int index, unsigned scale); + MemorySite(Register base, int offset, Register index, unsigned scale); virtual unsigned toString(Context*, char* buffer, unsigned bufferSize); @@ -351,16 +351,16 @@ class MemorySite : public Site { virtual bool isVolatile(Context* c); bool acquired; - int base; + Register base; int offset; - int index; + Register index; unsigned scale; }; MemorySite* memorySite(Context* c, - int base, + Register base, int offset = 0, - int index = lir::NoRegister, + Register index = Register::None, unsigned scale = 1); MemorySite* frameSite(Context* c, int frameIndex); diff --git a/src/codegen/registers.cpp b/src/codegen/registers.cpp index c4a0923b54..0df2325690 100644 --- a/src/codegen/registers.cpp +++ b/src/codegen/registers.cpp @@ -13,6 +13,8 @@ namespace avian { namespace codegen { +Register Register::None(-1); + unsigned BoundedRegisterMask::maskStart(RegisterMask mask) { for (int i = 0; i <= 31; ++i) { diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index bec887eab2..74ab3d6b43 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -164,37 +164,37 @@ class MyArchitecture : public Architecture { : &MyRegisterFileWithoutFloats; } - virtual int scratch() + virtual Register scratch() { return 5; } - virtual int stack() + virtual Register stack() { return StackRegister; } - virtual int thread() + virtual Register thread() { return ThreadRegister; } - virtual int returnLow() + virtual Register returnLow() { return 0; } - virtual int returnHigh() + virtual Register returnHigh() { return 1; } - virtual int virtualCallTarget() + virtual Register virtualCallTarget() { return 4; } - virtual int virtualCallIndex() + virtual Register virtualCallIndex() { return 3; } @@ -214,9 +214,9 @@ class MyArchitecture : public Architecture { return 0x1FFFFFF; } - virtual bool reserved(int register_) + virtual bool reserved(Register register_) { - switch (register_) { + switch ((int8_t)register_) { case LinkRegister: case StackRegister: case ThreadRegister: @@ -261,7 +261,7 @@ class MyArchitecture : public Architecture { return 4; } - virtual int argumentRegister(unsigned index) + virtual Register argumentRegister(unsigned index) { assertT(&con, index < argumentRegisterCount()); @@ -789,10 +789,10 @@ class MyAssembler : public Assembler { virtual void popFrameForTailCall(unsigned footprint, int offset, - int returnAddressSurrogate, - int framePointerSurrogate UNUSED) + Register returnAddressSurrogate, + Register framePointerSurrogate UNUSED) { - assertT(&con, framePointerSurrogate == lir::NoRegister); + assertT(&con, framePointerSurrogate == Register::None); if (TailCalls) { if (offset) { @@ -813,7 +813,7 @@ class MyAssembler : public Assembler { lir::Constant footprintConstant(&footprintPromise); addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); - if (returnAddressSurrogate != lir::NoRegister) { + if (returnAddressSurrogate != Register::None) { assertT(&con, offset > 0); lir::RegisterPair ras(returnAddressSurrogate); diff --git a/src/codegen/target/arm/encode.h b/src/codegen/target/arm/encode.h index edbeb3d071..1bbf385246 100644 --- a/src/codegen/target/arm/encode.h +++ b/src/codegen/target/arm/encode.h @@ -46,34 +46,34 @@ enum CONDITION { enum SHIFTOP { LSL, LSR, ASR, ROR }; // INSTRUCTION FORMATS inline int - DATA(int cond, int opcode, int S, int Rn, int Rd, int shift, int Sh, int Rm) + DATA(int cond, int opcode, int S, Register Rn, Register Rd, int shift, int Sh, Register Rm) { - return cond << 28 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12 | shift << 7 - | Sh << 5 | Rm; + return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7 + | Sh << 5 | (int8_t)Rm; } inline int - DATAS(int cond, int opcode, int S, int Rn, int Rd, int Rs, int Sh, int Rm) + DATAS(int cond, int opcode, int S, Register Rn, Register Rd, Register Rs, int Sh, Register Rm) { - return cond << 28 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12 | Rs << 8 - | Sh << 5 | 1 << 4 | Rm; + return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | (int8_t)Rs << 8 + | Sh << 5 | 1 << 4 | (int8_t)Rm; } -inline int DATAI(int cond, int opcode, int S, int Rn, int Rd, int rot, int imm) +inline int DATAI(int cond, int opcode, int S, Register Rn, Register Rd, int rot, int imm) { - return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12 + return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | rot << 8 | (imm & 0xff); } inline int BRANCH(int cond, int L, int offset) { return cond << 28 | 5 << 25 | L << 24 | (offset & 0xffffff); } -inline int BRANCHX(int cond, int L, int Rm) +inline int BRANCHX(int cond, int L, Register Rm) { - return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | Rm; + return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | (int8_t)Rm; } -inline int MULTIPLY(int cond, int mul, int S, int Rd, int Rn, int Rs, int Rm) +inline int MULTIPLY(int cond, int mul, int S, Register Rd, Register Rn, Register Rs, Register Rm) { - return cond << 28 | mul << 21 | S << 20 | Rd << 16 | Rn << 12 | Rs << 8 - | 9 << 4 | Rm; + return cond << 28 | mul << 21 | S << 20 | (int8_t)Rd << 16 | (int8_t)Rn << 12 | (int8_t)Rs << 8 + | 9 << 4 | (int8_t)Rm; } inline int XFER(int cond, int P, @@ -81,14 +81,14 @@ inline int XFER(int cond, int B, int W, int L, - int Rn, - int Rd, + Register Rn, + Register Rd, int shift, int Sh, - int Rm) + Register Rm) { return cond << 28 | 3 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20 - | Rn << 16 | Rd << 12 | shift << 7 | Sh << 5 | Rm; + | (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7 | Sh << 5 | (int8_t)Rm; } inline int XFERI(int cond, int P, @@ -96,53 +96,53 @@ inline int XFERI(int cond, int B, int W, int L, - int Rn, - int Rd, + Register Rn, + Register Rd, int offset) { return cond << 28 | 2 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20 - | Rn << 16 | Rd << 12 | (offset & 0xfff); + | (int8_t)Rn << 16 | (int8_t)Rd << 12 | (offset & 0xfff); } inline int XFER2(int cond, int P, int U, int W, int L, - int Rn, - int Rd, + Register Rn, + Register Rd, int S, int H, - int Rm) + Register Rm) { - return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | Rn << 16 - | Rd << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | Rm; + return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | (int8_t)Rn << 16 + | (int8_t)Rd << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | (int8_t)Rm; } inline int XFER2I(int cond, int P, int U, int W, int L, - int Rn, - int Rd, + Register Rn, + Register Rd, int offsetH, int S, int H, int offsetL) { - return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | Rn << 16 - | Rd << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4 + return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | (int8_t)Rn << 16 + | (int8_t)Rd << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | (offsetL & 0xf); } inline int COOP(int cond, int opcode_1, - int CRn, - int CRd, + Register CRn, + Register CRd, int cp_num, int opcode_2, - int CRm) + Register CRm) { - return cond << 28 | 0xe << 24 | opcode_1 << 20 | CRn << 16 | CRd << 12 - | cp_num << 8 | opcode_2 << 5 | CRm; + return cond << 28 | 0xe << 24 | opcode_1 << 20 | (int8_t)CRn << 16 | (int8_t)CRd << 12 + | cp_num << 8 | opcode_2 << 5 | (int8_t)CRm; } inline int COXFER(int cond, int P, @@ -150,31 +150,31 @@ inline int COXFER(int cond, int N, int W, int L, - int Rn, - int CRd, + Register Rn, + Register CRd, int cp_num, int offset) // offset is in words, not bytes { return cond << 28 | 0x6 << 25 | P << 24 | U << 23 | N << 22 | W << 21 - | L << 20 | Rn << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; + | L << 20 | (int8_t)Rn << 16 | (int8_t)CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; } inline int COREG(int cond, int opcode_1, int L, - int CRn, - int Rd, + Register CRn, + Register Rd, int cp_num, int opcode_2, - int CRm) + Register CRm) { - return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | CRn << 16 - | Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm; + return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | (int8_t)CRn << 16 + | (int8_t)Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | (int8_t)CRm; } inline int - COREG2(int cond, int L, int Rn, int Rd, int cp_num, int opcode, int CRm) + COREG2(int cond, int L, Register Rn, Register Rd, int cp_num, int opcode, Register CRm) { - return cond << 28 | 0xc4 << 20 | L << 20 | Rn << 16 | Rd << 12 | cp_num << 8 - | opcode << 4 | CRm; + return cond << 28 | 0xc4 << 20 | L << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | cp_num << 8 + | opcode << 4 | (int8_t)CRm; } // FIELD CALCULATORS inline int calcU(int imm) @@ -191,143 +191,143 @@ inline int bl(int offset) { return BRANCH(AL, 1, offset); } -inline int bx(int Rm) +inline int bx(Register Rm) { return BRANCHX(AL, 0, Rm); } -inline int blx(int Rm) +inline int blx(Register Rm) { return BRANCHX(AL, 1, Rm); } -inline int and_(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0) +inline int and_(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0x0, 0, Rn, Rd, shift, Sh, Rm); } -inline int eor(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0) +inline int eor(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0x1, 0, Rn, Rd, shift, Sh, Rm); } -inline int rsb(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0) +inline int rsb(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0x3, 0, Rn, Rd, shift, Sh, Rm); } -inline int add(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0) +inline int add(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0x4, 0, Rn, Rd, shift, Sh, Rm); } -inline int adc(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0) +inline int adc(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0x5, 0, Rn, Rd, shift, Sh, Rm); } -inline int rsc(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0) +inline int rsc(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0x7, 0, Rn, Rd, shift, Sh, Rm); } -inline int cmp(int Rn, int Rm, int Sh = 0, int shift = 0) +inline int cmp(Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0xa, 1, Rn, 0, shift, Sh, Rm); } -inline int orr(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0) +inline int orr(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0xc, 0, Rn, Rd, shift, Sh, Rm); } -inline int mov(int Rd, int Rm, int Sh = 0, int shift = 0) +inline int mov(Register Rd, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0xd, 0, 0, Rd, shift, Sh, Rm); } -inline int mvn(int Rd, int Rm, int Sh = 0, int shift = 0) +inline int mvn(Register Rd, Register Rm, int Sh = 0, int shift = 0) { return DATA(AL, 0xf, 0, 0, Rd, shift, Sh, Rm); } -inline int andi(int Rd, int Rn, int imm, int rot = 0) +inline int andi(Register Rd, Register Rn, int imm, int rot = 0) { return DATAI(AL, 0x0, 0, Rn, Rd, rot, imm); } -inline int subi(int Rd, int Rn, int imm, int rot = 0) +inline int subi(Register Rd, Register Rn, int imm, int rot = 0) { return DATAI(AL, 0x2, 0, Rn, Rd, rot, imm); } -inline int rsbi(int Rd, int Rn, int imm, int rot = 0) +inline int rsbi(Register Rd, Register Rn, int imm, int rot = 0) { return DATAI(AL, 0x3, 0, Rn, Rd, rot, imm); } -inline int addi(int Rd, int Rn, int imm, int rot = 0) +inline int addi(Register Rd, Register Rn, int imm, int rot = 0) { return DATAI(AL, 0x4, 0, Rn, Rd, rot, imm); } -inline int adci(int Rd, int Rn, int imm, int rot = 0) +inline int adci(Register Rd, Register Rn, int imm, int rot = 0) { return DATAI(AL, 0x5, 0, Rn, Rd, rot, imm); } -inline int bici(int Rd, int Rn, int imm, int rot = 0) +inline int bici(Register Rd, Register Rn, int imm, int rot = 0) { return DATAI(AL, 0xe, 0, Rn, Rd, rot, imm); } -inline int cmpi(int Rn, int imm, int rot = 0) +inline int cmpi(Register Rn, int imm, int rot = 0) { return DATAI(AL, 0xa, 1, Rn, 0, rot, imm); } -inline int movi(int Rd, int imm, int rot = 0) +inline int movi(Register Rd, int imm, int rot = 0) { return DATAI(AL, 0xd, 0, 0, Rd, rot, imm); } -inline int orrsh(int Rd, int Rn, int Rm, int Rs, int Sh) +inline int orrsh(Register Rd, Register Rn, Register Rm, Register Rs, int Sh) { return DATAS(AL, 0xc, 0, Rn, Rd, Rs, Sh, Rm); } -inline int movsh(int Rd, int Rm, int Rs, int Sh) +inline int movsh(Register Rd, Register Rm, Register Rs, int Sh) { return DATAS(AL, 0xd, 0, 0, Rd, Rs, Sh, Rm); } -inline int mul(int Rd, int Rm, int Rs) +inline int mul(Register Rd, Register Rm, Register Rs) { return MULTIPLY(AL, 0, 0, Rd, 0, Rs, Rm); } -inline int mla(int Rd, int Rm, int Rs, int Rn) +inline int mla(Register Rd, Register Rm, Register Rs, Register Rn) { return MULTIPLY(AL, 1, 0, Rd, Rn, Rs, Rm); } -inline int umull(int RdLo, int RdHi, int Rm, int Rs) +inline int umull(Register RdLo, Register RdHi, Register Rm, Register Rs) { return MULTIPLY(AL, 4, 0, RdHi, RdLo, Rs, Rm); } -inline int ldr(int Rd, int Rn, int Rm, int W = 0) +inline int ldr(Register Rd, Register Rn, Register Rm, int W = 0) { return XFER(AL, 1, 1, 0, W, 1, Rn, Rd, 0, 0, Rm); } -inline int ldri(int Rd, int Rn, int imm, int W = 0) +inline int ldri(Register Rd, Register Rn, int imm, int W = 0) { return XFERI(AL, 1, calcU(imm), 0, W, 1, Rn, Rd, abs(imm)); } -inline int ldrb(int Rd, int Rn, int Rm) +inline int ldrb(Register Rd, Register Rn, Register Rm) { return XFER(AL, 1, 1, 1, 0, 1, Rn, Rd, 0, 0, Rm); } -inline int ldrbi(int Rd, int Rn, int imm) +inline int ldrbi(Register Rd, Register Rn, int imm) { return XFERI(AL, 1, calcU(imm), 1, 0, 1, Rn, Rd, abs(imm)); } -inline int str(int Rd, int Rn, int Rm, int W = 0) +inline int str(Register Rd, Register Rn, Register Rm, int W = 0) { return XFER(AL, 1, 1, 0, W, 0, Rn, Rd, 0, 0, Rm); } -inline int stri(int Rd, int Rn, int imm, int W = 0) +inline int stri(Register Rd, Register Rn, int imm, int W = 0) { return XFERI(AL, 1, calcU(imm), 0, W, 0, Rn, Rd, abs(imm)); } -inline int strb(int Rd, int Rn, int Rm) +inline int strb(Register Rd, Register Rn, Register Rm) { return XFER(AL, 1, 1, 1, 0, 0, Rn, Rd, 0, 0, Rm); } -inline int strbi(int Rd, int Rn, int imm) +inline int strbi(Register Rd, Register Rn, int imm) { return XFERI(AL, 1, calcU(imm), 1, 0, 0, Rn, Rd, abs(imm)); } -inline int ldrh(int Rd, int Rn, int Rm) +inline int ldrh(Register Rd, Register Rn, Register Rm) { return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 0, 1, Rm); } -inline int ldrhi(int Rd, int Rn, int imm) +inline int ldrhi(Register Rd, Register Rn, int imm) { return XFER2I(AL, 1, @@ -341,11 +341,11 @@ inline int ldrhi(int Rd, int Rn, int imm) 1, abs(imm) & 0xf); } -inline int strh(int Rd, int Rn, int Rm) +inline int strh(Register Rd, Register Rn, Register Rm) { return XFER2(AL, 1, 1, 0, 0, Rn, Rd, 0, 1, Rm); } -inline int strhi(int Rd, int Rn, int imm) +inline int strhi(Register Rd, Register Rn, int imm) { return XFER2I(AL, 1, @@ -359,11 +359,11 @@ inline int strhi(int Rd, int Rn, int imm) 1, abs(imm) & 0xf); } -inline int ldrsh(int Rd, int Rn, int Rm) +inline int ldrsh(Register Rd, Register Rn, Register Rm) { return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 1, Rm); } -inline int ldrshi(int Rd, int Rn, int imm) +inline int ldrshi(Register Rd, Register Rn, int imm) { return XFER2I(AL, 1, @@ -377,11 +377,11 @@ inline int ldrshi(int Rd, int Rn, int imm) 1, abs(imm) & 0xf); } -inline int ldrsb(int Rd, int Rn, int Rm) +inline int ldrsb(Register Rd, Register Rn, Register Rm) { return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 0, Rm); } -inline int ldrsbi(int Rd, int Rn, int imm) +inline int ldrsbi(Register Rd, Register Rn, int imm) { return XFER2I(AL, 1, @@ -403,70 +403,70 @@ inline int bkpt(int16_t immed) // COPROCESSOR INSTRUCTIONS inline int mcr(int coproc, int opcode_1, - int Rd, - int CRn, - int CRm, + Register Rd, + Register CRn, + Register CRm, int opcode_2 = 0) { return COREG(AL, opcode_1, 0, CRn, Rd, coproc, opcode_2, CRm); } -inline int mcrr(int coproc, int opcode, int Rd, int Rn, int CRm) +inline int mcrr(int coproc, int opcode, Register Rd, Register Rn, Register CRm) { return COREG2(AL, 0, Rn, Rd, coproc, opcode, CRm); } inline int mrc(int coproc, int opcode_1, - int Rd, - int CRn, - int CRm, + Register Rd, + Register CRn, + Register CRm, int opcode_2 = 0) { return COREG(AL, opcode_1, 1, CRn, Rd, coproc, opcode_2, CRm); } -inline int mrrc(int coproc, int opcode, int Rd, int Rn, int CRm) +inline int mrrc(int coproc, int opcode, Register Rd, Register Rn, Register CRm) { return COREG2(AL, 1, Rn, Rd, coproc, opcode, CRm); } // VFP FLOATING-POINT INSTRUCTIONS -inline int fmuls(int Sd, int Sn, int Sm) +inline int fmuls(Register Sd, Register Sn, Register Sm) { return COOP(AL, - (Sd & 1) << 2 | 2, - Sn >> 1, - Sd >> 1, + ((int8_t)Sd & 1) << 2 | 2, + (int8_t)Sn >> 1, + (int8_t)Sd >> 1, 10, - (Sn & 1) << 2 | (Sm & 1), - Sm >> 1); + ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), + (int8_t)Sm >> 1); } -inline int fadds(int Sd, int Sn, int Sm) +inline int fadds(Register Sd, Register Sn, Register Sm) { return COOP(AL, - (Sd & 1) << 2 | 3, - Sn >> 1, - Sd >> 1, + ((int8_t)Sd & 1) << 2 | 3, + (int8_t)Sn >> 1, + (int8_t)Sd >> 1, 10, - (Sn & 1) << 2 | (Sm & 1), - Sm >> 1); + ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), + (int8_t)Sm >> 1); } -inline int fsubs(int Sd, int Sn, int Sm) +inline int fsubs(Register Sd, Register Sn, Register Sm) { return COOP(AL, - (Sd & 1) << 2 | 3, - Sn >> 1, - Sd >> 1, + ((int8_t)Sd & 1) << 2 | 3, + (int8_t)Sn >> 1, + (int8_t)Sd >> 1, 10, - (Sn & 1) << 2 | (Sm & 1) | 2, - Sm >> 1); + ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1) | 2, + (int8_t)Sm >> 1); } -inline int fdivs(int Sd, int Sn, int Sm) +inline int fdivs(Register Sd, Register Sn, Register Sm) { return COOP(AL, - (Sd & 1) << 2 | 8, - Sn >> 1, - Sd >> 1, + ((int8_t)Sd & 1) << 2 | 8, + (int8_t)Sn >> 1, + (int8_t)Sd >> 1, 10, - (Sn & 1) << 2 | (Sm & 1), - Sm >> 1); + ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), + (int8_t)Sm >> 1); } inline int fmuld(int Dd, int Dn, int Dm) { @@ -484,37 +484,37 @@ inline int fdivd(int Dd, int Dn, int Dm) { return COOP(AL, 8, Dn, Dd, 11, 0, Dm); } -inline int fcpys(int Sd, int Sm) +inline int fcpys(Register Sd, Register Sm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fabss(int Sd, int Sm) +inline int fabss(Register Sd, Register Sm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fnegs(int Sd, int Sm) +inline int fnegs(Register Sd, Register Sm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 1, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fsqrts(int Sd, int Sm) +inline int fsqrts(Register Sd, Register Sm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 1, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fcmps(int Sd, int Sm) +inline int fcmps(Register Sd, Register Sm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 4, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 4, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fcvtds(int Dd, int Sm) +inline int fcvtds(int Dd, Register Sm) { - return COOP(AL, 0xb, 7, Dd, 10, 6 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb, 7, Dd, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fsitos(int Sd, int Sm) +inline int fsitos(Register Sd, Register Sm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 8, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 8, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int ftosizs(int Sd, int Sm) +inline int ftosizs(Register Sd, Register Sm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0xd, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } inline int fcpyd(int Dd, int Dm) { @@ -538,55 +538,55 @@ inline int fcmpd(int Dd, int Dm) return COOP(AL, 0xb, 4, Dd, 11, 2, Dm); } // double-precision conversion instructions -inline int fcvtsd(int Sd, int Dm) +inline int fcvtsd(Register Sd, int Dm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 7, Sd >> 1, 11, 6, Dm); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 7, (int8_t)Sd >> 1, 11, 6, Dm); } -inline int fsitod(int Dd, int Sm) +inline int fsitod(Register Dd, Register Sm) { - return COOP(AL, 0xb, 8, Dd, 11, 6 | (Sm & 1), Sm >> 1); + return COOP(AL, 0xb, 8, Dd, 11, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int ftosizd(int Sd, int Dm) +inline int ftosizd(Register Sd, Register Dm) { - return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 11, 6, Dm); + return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0xd, (int8_t)Sd >> 1, 11, 6, Dm); } // single load/store instructions for both precision types -inline int flds(int Sd, int Rn, int offset = 0) +inline int flds(Register Sd, Register Rn, int offset = 0) { - return COXFER(AL, 1, 1, Sd & 1, 0, 1, Rn, Sd >> 1, 10, offset); + return COXFER(AL, 1, 1, (int8_t)Sd & 1, 0, 1, Rn, (int8_t)Sd >> 1, 10, offset); }; -inline int fldd(int Dd, int Rn, int offset = 0) +inline int fldd(Register Dd, Register Rn, int offset = 0) { return COXFER(AL, 1, 1, 0, 0, 1, Rn, Dd, 11, offset); }; -inline int fsts(int Sd, int Rn, int offset = 0) +inline int fsts(Register Sd, Register Rn, int offset = 0) { - return COXFER(AL, 1, 1, Sd & 1, 0, 0, Rn, Sd >> 1, 10, offset); + return COXFER(AL, 1, 1, (int8_t)Sd & 1, 0, 0, Rn, (int8_t)Sd >> 1, 10, offset); }; -inline int fstd(int Dd, int Rn, int offset = 0) +inline int fstd(Register Dd, Register Rn, int offset = 0) { return COXFER(AL, 1, 1, 0, 0, 0, Rn, Dd, 11, offset); }; // move between GPRs and FPRs -inline int fmsr(int Sn, int Rd) +inline int fmsr(Register Sn, Register Rd) { - return mcr(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2); + return mcr(10, 0, Rd, (int8_t)Sn >> 1, 0, ((int8_t)Sn & 1) << 2); } -inline int fmrs(int Rd, int Sn) +inline int fmrs(Register Rd, Register Sn) { - return mrc(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2); + return mrc(10, 0, Rd, (int8_t)Sn >> 1, 0, ((int8_t)Sn & 1) << 2); } // move to/from VFP system registers -inline int fmrx(int Rd, int reg) +inline int fmrx(Register Rd, int reg) { return mrc(10, 7, Rd, reg, 0); } // these move around pairs of single-precision registers -inline int fmdrr(int Dm, int Rd, int Rn) +inline int fmdrr(Register Dm, Register Rd, Register Rn) { return mcrr(11, 1, Rd, Rn, Dm); } -inline int fmrrd(int Rd, int Rn, int Dm) +inline int fmrrd(Register Rd, Register Rn, int Dm) { return mrrc(11, 1, Rd, Rn, Dm); } @@ -600,27 +600,27 @@ inline int SETS(int ins) return ins | 1 << 20; } // PSEUDO-INSTRUCTIONS -inline int lsl(int Rd, int Rm, int Rs) +inline int lsl(Register Rd, Register Rm, Register Rs) { return movsh(Rd, Rm, Rs, LSL); } -inline int lsli(int Rd, int Rm, int imm) +inline int lsli(Register Rd, Register Rm, int imm) { return mov(Rd, Rm, LSL, imm); } -inline int lsr(int Rd, int Rm, int Rs) +inline int lsr(Register Rd, Register Rm, Register Rs) { return movsh(Rd, Rm, Rs, LSR); } -inline int lsri(int Rd, int Rm, int imm) +inline int lsri(Register Rd, Register Rm, int imm) { return mov(Rd, Rm, LSR, imm); } -inline int asr(int Rd, int Rm, int Rs) +inline int asr(Register Rd, Register Rm, Register Rs) { return movsh(Rd, Rm, Rs, ASR); } -inline int asri(int Rd, int Rm, int imm) +inline int asri(Register Rd, Register Rm, int imm) { return mov(Rd, Rm, ASR, imm); } diff --git a/src/codegen/target/arm/operations.cpp b/src/codegen/target/arm/operations.cpp index 1fa365c7b7..627d2c81d2 100644 --- a/src/codegen/target/arm/operations.cpp +++ b/src/codegen/target/arm/operations.cpp @@ -45,7 +45,7 @@ void shiftLeftR(Context* con, lir::RegisterPair* t) { if (size == 8) { - int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); + Register tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); ResolvedPromise maskPromise(0x3F); lir::Constant mask(&maskPromise); lir::RegisterPair dst(tmp3); @@ -61,7 +61,7 @@ void shiftLeftR(Context* con, freeTemp(con, tmp2); freeTemp(con, tmp3); } else { - int tmp = newTemp(con); + Register tmp = newTemp(con); ResolvedPromise maskPromise(0x1F); lir::Constant mask(&maskPromise); lir::RegisterPair dst(tmp); @@ -98,7 +98,7 @@ void shiftRightR(Context* con, lir::RegisterPair* t) { if (size == 8) { - int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); + Register tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); ResolvedPromise maskPromise(0x3F); lir::Constant mask(&maskPromise); lir::RegisterPair dst(tmp3); @@ -114,7 +114,7 @@ void shiftRightR(Context* con, freeTemp(con, tmp2); freeTemp(con, tmp3); } else { - int tmp = newTemp(con); + Register tmp = newTemp(con); ResolvedPromise maskPromise(0x1F); lir::Constant mask(&maskPromise); lir::RegisterPair dst(tmp); @@ -144,14 +144,14 @@ void unsignedShiftRightR(Context* con, lir::RegisterPair* b, lir::RegisterPair* t) { - int tmpShift = newTemp(con); + Register tmpShift = newTemp(con); ResolvedPromise maskPromise(size == 8 ? 0x3F : 0x1F); lir::Constant mask(&maskPromise); lir::RegisterPair dst(tmpShift); andC(con, 4, &mask, a, &dst); emit(con, lsr(t->low, b->low, tmpShift)); if (size == 8) { - int tmpHi = newTemp(con), tmpLo = newTemp(con); + Register tmpHi = newTemp(con), tmpLo = newTemp(con); emit(con, SETS(rsbi(tmpHi, tmpShift, 32))); emit(con, lsl(tmpLo, b->high, tmpHi)); emit(con, orr(t->low, t->low, tmpLo)); @@ -509,9 +509,9 @@ void multiplyR(Context* con, { if (size == 8) { bool useTemporaries = b->low == t->low; - int tmpLow = useTemporaries ? con->client->acquireTemporary(GPR_MASK) + Register tmpLow = useTemporaries ? con->client->acquireTemporary(GPR_MASK) : t->low; - int tmpHigh = useTemporaries ? con->client->acquireTemporary(GPR_MASK) + Register tmpHigh = useTemporaries ? con->client->acquireTemporary(GPR_MASK) : t->high; emit(con, umull(tmpLow, tmpHigh, a->low, b->low)); @@ -574,8 +574,8 @@ void float2IntRR(Context* con, unsigned, lir::RegisterPair* b) { - int tmp = newTemp(con, FPR_MASK); - int ftmp = fpr32(tmp); + Register tmp = newTemp(con, FPR_MASK); + Register ftmp = fpr32(tmp); if (size == 8) { // double to int emit(con, ftosizd(ftmp, fpr64(a))); } else { // float to int @@ -664,9 +664,9 @@ void floatDivideR(Context* con, } } -int normalize(Context* con, +Register normalize(Context* con, int offset, - int index, + Register index, unsigned scale, bool* preserveIndex, bool* release) @@ -682,7 +682,7 @@ int normalize(Context* con, *release = false; } - int scaled; + Register scaled; if (scale != 1) { lir::RegisterPair unscaledIndex(index); @@ -731,15 +731,15 @@ int normalize(Context* con, void store(Context* con, unsigned size, lir::RegisterPair* src, - int base, + Register base, int offset, - int index, + Register index, unsigned scale, bool preserveIndex) { - if (index != lir::NoRegister) { + if (index != Register::None) { bool release; - int normalized + Register normalized = normalize(con, offset, index, scale, &preserveIndex, &release); if (!isFpr(src)) { // GPR store @@ -799,8 +799,8 @@ void store(Context* con, case 8: { // split into 2 32-bit stores lir::RegisterPair srcHigh(src->high); - store(con, 4, &srcHigh, base, offset, lir::NoRegister, 1, false); - store(con, 4, src, base, offset + 4, lir::NoRegister, 1, false); + store(con, 4, &srcHigh, base, offset, Register::None, 1, false); + store(con, 4, src, base, offset + 4, Register::None, 1, false); } break; default: @@ -844,18 +844,18 @@ void moveRM(Context* con, void load(Context* con, unsigned srcSize, - int base, + Register base, int offset, - int index, + Register index, unsigned scale, unsigned dstSize, lir::RegisterPair* dst, bool preserveIndex, bool signExtend) { - if (index != lir::NoRegister) { + if (index != Register::None) { bool release; - int normalized + Register normalized = normalize(con, offset, index, scale, &preserveIndex, &release); if (!isFpr(dst)) { // GPR load @@ -951,7 +951,7 @@ void load(Context* con, 4, base, offset, - lir::NoRegister, + Register::None, 1, 4, &dstHigh, @@ -961,7 +961,7 @@ void load(Context* con, 4, base, offset + 4, - lir::NoRegister, + Register::None, 1, 4, dst, diff --git a/src/codegen/target/arm/operations.h b/src/codegen/target/arm/operations.h index 4135bedbf4..aa7492d589 100644 --- a/src/codegen/target/arm/operations.h +++ b/src/codegen/target/arm/operations.h @@ -59,9 +59,9 @@ inline lir::RegisterPair makeTemp64(Context* con) inline void freeTemp(Context* con, const lir::RegisterPair& tmp) { - if (tmp.low != lir::NoRegister) + if (tmp.low != Register::None) freeTemp(con, tmp.low); - if (tmp.high != lir::NoRegister) + if (tmp.high != Register::None) freeTemp(con, tmp.high); } diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index 7d94af2349..900ef58019 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -28,18 +28,18 @@ const RegisterMask FPR_MASK = 0xffff0000; inline bool isFpr(lir::RegisterPair* reg) { - return reg->low >= N_GPRS; + return (int8_t)reg->low >= N_GPRS; } -inline int fpr64(int reg) +inline int fpr64(Register reg) { - return reg - N_GPRS; + return (int8_t)reg - N_GPRS; } inline int fpr64(lir::RegisterPair* reg) { return fpr64(reg->low); } -inline int fpr32(int reg) +inline int fpr32(Register reg) { return fpr64(reg) << 1; } diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index e91ffc6c8b..f6c4a0b87b 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -183,37 +183,37 @@ class MyArchitecture : public Architecture { return &myRegisterFile; } - virtual int scratch() + virtual Register scratch() { return rax; } - virtual int stack() + virtual Register stack() { return rsp; } - virtual int thread() + virtual Register thread() { return rbx; } - virtual int returnLow() + virtual Register returnLow() { return rax; } - virtual int returnHigh() + virtual Register returnHigh() { - return (TargetBytesPerWord == 4 ? rdx : lir::NoRegister); + return (TargetBytesPerWord == 4 ? rdx : Register::None); } - virtual int virtualCallTarget() + virtual Register virtualCallTarget() { return rax; } - virtual int virtualCallIndex() + virtual Register virtualCallIndex() { return rdx; } @@ -233,9 +233,9 @@ class MyArchitecture : public Architecture { return 0x7FFFFFFF; } - virtual bool reserved(int register_) + virtual bool reserved(Register register_) { - switch (register_) { + switch ((int8_t)register_) { case rbp: return UseFramePointer; @@ -289,7 +289,7 @@ class MyArchitecture : public Architecture { return 0; } - virtual int argumentRegister(unsigned index) + virtual Register argumentRegister(unsigned index) { assertT(&c, TargetBytesPerWord == 8); switch (index) { @@ -1031,8 +1031,8 @@ class MyAssembler : public Assembler { virtual void popFrameForTailCall(unsigned frameFootprint, int offset, - int returnAddressSurrogate, - int framePointerSurrogate) + Register returnAddressSurrogate, + Register framePointerSurrogate) { if (TailCalls) { if (offset) { @@ -1070,7 +1070,7 @@ class MyAssembler : public Assembler { addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack); - if (returnAddressSurrogate != lir::NoRegister) { + if (returnAddressSurrogate != Register::None) { assertT(&c, offset > 0); lir::RegisterPair ras(returnAddressSurrogate); @@ -1078,7 +1078,7 @@ class MyAssembler : public Assembler { moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } - if (framePointerSurrogate != lir::NoRegister) { + if (framePointerSurrogate != Register::None) { assertT(&c, offset > 0); lir::RegisterPair fps(framePointerSurrogate); diff --git a/src/codegen/target/x86/encode.cpp b/src/codegen/target/x86/encode.cpp index 7911bb7cc1..fe7275a24c 100644 --- a/src/codegen/target/x86/encode.cpp +++ b/src/codegen/target/x86/encode.cpp @@ -53,9 +53,9 @@ namespace x86 { void maybeRex(Context* c, unsigned size, - int a, - int index, - int base, + Register a, + Register index, + Register base, bool always) { if (vm::TargetBytesPerWord == 8) { @@ -65,11 +65,11 @@ void maybeRex(Context* c, } else { byte = REX_NONE; } - if (a != lir::NoRegister and (a & 8)) + if (a != Register::None and ((int8_t)a & 8)) byte |= REX_R; - if (index != lir::NoRegister and (index & 8)) + if (index != Register::None and ((int8_t)index & 8)) byte |= REX_X; - if (base != lir::NoRegister and (base & 8)) + if (base != Register::None and ((int8_t)base & 8)) byte |= REX_B; if (always or byte != REX_NONE) c->code.append(byte); @@ -78,30 +78,30 @@ void maybeRex(Context* c, void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b) { - maybeRex(c, size, a->low, lir::NoRegister, b->low, false); + maybeRex(c, size, a->low, Register::None, b->low, false); } void alwaysRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b) { - maybeRex(c, size, a->low, lir::NoRegister, b->low, true); + maybeRex(c, size, a->low, Register::None, b->low, true); } void maybeRex(Context* c, unsigned size, lir::RegisterPair* a) { - maybeRex(c, size, lir::NoRegister, lir::NoRegister, a->low, false); + maybeRex(c, size, Register::None, Register::None, a->low, false); } void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b) { - maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low & 4)); + maybeRex(c, size, a->low, b->index, b->base, size == 1 and ((int8_t)a->low & 4)); } void maybeRex(Context* c, unsigned size, lir::Memory* a) { - maybeRex(c, size, lir::NoRegister, a->index, a->base, false); + maybeRex(c, size, Register::None, a->index, a->base, false); } -void modrm(Context* c, uint8_t mod, int a, int b) +void modrm(Context* c, uint8_t mod, Register a, Register b) { c->code.append(mod | (regCode(b) << 3) | regCode(a)); } @@ -111,15 +111,15 @@ void modrm(Context* c, uint8_t mod, lir::RegisterPair* a, lir::RegisterPair* b) modrm(c, mod, a->low, b->low); } -void sib(Context* c, unsigned scale, int index, int base) +void sib(Context* c, unsigned scale, Register index, Register base) { c->code.append((util::log(scale) << 6) | (regCode(index) << 3) | regCode(base)); } -void modrmSib(Context* c, int width, int a, int scale, int index, int base) +void modrmSib(Context* c, int width, Register a, int scale, Register index, Register base) { - if (index == lir::NoRegister) { + if (index == Register::None) { modrm(c, width, base, a); if (regCode(base) == rsp) { sib(c, 0x00, rsp, rsp); @@ -130,7 +130,7 @@ void modrmSib(Context* c, int width, int a, int scale, int index, int base) } } -void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset) +void modrmSibImm(Context* c, Register a, int scale, Register index, Register base, int offset) { if (offset == 0 and regCode(base) != rbp) { modrmSib(c, 0x00, a, scale, index, base); diff --git a/src/codegen/target/x86/encode.h b/src/codegen/target/x86/encode.h index a51f27b725..4e5f0e6c0c 100644 --- a/src/codegen/target/x86/encode.h +++ b/src/codegen/target/x86/encode.h @@ -42,9 +42,9 @@ void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b); void maybeRex(Context* c, unsigned size, lir::Memory* a); -inline int regCode(int a) +inline int regCode(Register a) { - return a & 7; + return (int8_t)a & 7; } inline int regCode(lir::RegisterPair* a) @@ -54,18 +54,18 @@ inline int regCode(lir::RegisterPair* a) inline bool isFloatReg(lir::RegisterPair* a) { - return a->low >= xmm0; + return (int8_t)a->low >= xmm0; } -void modrm(Context* c, uint8_t mod, int a, int b); +void modrm(Context* c, uint8_t mod, Register a, Register b); void modrm(Context* c, uint8_t mod, lir::RegisterPair* a, lir::RegisterPair* b); -void sib(Context* c, unsigned scale, int index, int base); +void sib(Context* c, unsigned scale, Register index, Register base); -void modrmSib(Context* c, int width, int a, int scale, int index, int base); +void modrmSib(Context* c, int width, Register a, int scale, Register index, Register base); -void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset); +void modrmSibImm(Context* c, Register a, int scale, Register index, Register base, int offset); void modrmSibImm(Context* c, lir::RegisterPair* a, lir::Memory* b); diff --git a/src/codegen/target/x86/operations.cpp b/src/codegen/target/x86/operations.cpp index b9229ea0aa..c61ef64477 100644 --- a/src/codegen/target/x86/operations.cpp +++ b/src/codegen/target/x86/operations.cpp @@ -308,8 +308,8 @@ void moveRR(Context* c, } else { switch (aSize) { case 1: - if (vm::TargetBytesPerWord == 4 and a->low > rbx) { - assertT(c, b->low <= rbx); + if (vm::TargetBytesPerWord == 4 and (int8_t)a->low > rbx) { + assertT(c, (int8_t)b->low <= rbx); moveRR(c, vm::TargetBytesPerWord, a, vm::TargetBytesPerWord, b); moveRR(c, 1, b, vm::TargetBytesPerWord, b); @@ -986,7 +986,7 @@ void multiplyRR(Context* c, addRR(c, 4, &bh, 4, scratch); // mul a->low,%eax%edx - opcode(c, 0xf7, 0xe0 + a->low); + opcode(c, 0xf7, 0xe0 + (int8_t)a->low); addRR(c, 4, scratch, 4, &bh); moveRR(c, 4, &axdx, 4, b); @@ -1403,7 +1403,7 @@ void shiftLeftRR(Context* c, modrm(c, 0xc0, b->high, b->low); // shl - opcode(c, 0xd3, 0xe0 + b->low); + opcode(c, 0xd3, 0xe0 + (int8_t)b->low); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1454,7 +1454,7 @@ void shiftRightRR(Context* c, modrm(c, 0xc0, b->low, b->high); // sar - opcode(c, 0xd3, 0xf8 + b->high); + opcode(c, 0xd3, 0xf8 + (int8_t)b->high); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1468,7 +1468,7 @@ void shiftRightRR(Context* c, moveRR(c, 4, &bh, 4, b); // 2 bytes // sar 31,high - opcode(c, 0xc1, 0xf8 + b->high); + opcode(c, 0xc1, 0xf8 + (int8_t)b->high); c->code.append(31); } else { assertT(c, a->low == rcx); @@ -1508,7 +1508,7 @@ void unsignedShiftRightRR(Context* c, modrm(c, 0xc0, b->low, b->high); // shr - opcode(c, 0xd3, 0xe8 + b->high); + opcode(c, 0xd3, 0xe8 + (int8_t)b->high); ResolvedPromise promise(32); lir::Constant constant(&promise); diff --git a/unittest/codegen/registers-test.cpp b/unittest/codegen/registers-test.cpp index 392fc8e26e..c7e9ec8d42 100644 --- a/unittest/codegen/registers-test.cpp +++ b/unittest/codegen/registers-test.cpp @@ -25,12 +25,12 @@ TEST(RegisterIterator) RegisterIterator it(regs); assertTrue(it.hasNext()); - assertEqual(0, it.next()); + assertEqual(0, (int8_t)it.next()); assertTrue(it.hasNext()); - assertEqual(2, it.next()); + assertEqual(2, (int8_t)it.next()); assertTrue(it.hasNext()); - assertEqual(4, it.next()); + assertEqual(4, (int8_t)it.next()); assertTrue(it.hasNext()); - assertEqual(6, it.next()); + assertEqual(6, (int8_t)it.next()); assertFalse(it.hasNext()); } From 3bad154602dcf992185f83fe7b1905e8ccffd559 Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 22:01:16 -0700 Subject: [PATCH 19/70] add back NoRegister and remove some implicit int->Register casts --- include/avian/codegen/lir.h | 2 - include/avian/codegen/registers.h | 42 +++++++++-------- src/codegen/compiler.cpp | 2 +- src/codegen/compiler/context.cpp | 4 +- src/codegen/compiler/event.cpp | 12 ++--- src/codegen/compiler/regalloc.cpp | 10 ++-- src/codegen/compiler/resource.cpp | 4 +- src/codegen/compiler/resource.h | 2 +- src/codegen/compiler/site.cpp | 66 +++++++++++++-------------- src/codegen/compiler/site.h | 2 +- src/codegen/registers.cpp | 6 +-- src/codegen/target/arm/assembler.cpp | 4 +- src/codegen/target/arm/operations.cpp | 12 ++--- src/codegen/target/arm/operations.h | 4 +- src/codegen/target/x86/assembler.cpp | 6 +-- src/codegen/target/x86/encode.cpp | 16 +++---- 16 files changed, 97 insertions(+), 97 deletions(-) diff --git a/include/avian/codegen/lir.h b/include/avian/codegen/lir.h index 66289a616e..08c0fb3ee0 100644 --- a/include/avian/codegen/lir.h +++ b/include/avian/codegen/lir.h @@ -83,8 +83,6 @@ const unsigned BranchOperationCount = JumpIfFloatGreaterOrEqualOrUnordered enum ValueType { ValueGeneral, ValueFloat }; -const int NoRegister = -1; - inline bool isBranch(lir::TernaryOperation op) { return op > FloatMin; diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 404e65fd46..d86b122715 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -20,33 +20,33 @@ class Register { private: int8_t index; public: - Register(int8_t index) : index(index) {} - Register() : index(0xff) {} + constexpr Register(int8_t index) : index(index) {} + constexpr Register() : index(-1) {} - bool operator == (Register o) const { + constexpr bool operator == (Register o) const { return index == o.index; } - bool operator != (Register o) const { + constexpr bool operator != (Register o) const { return !(*this == o); } - explicit operator int8_t() const { + constexpr explicit operator int8_t() const { return index; } - - static Register None; }; +constexpr Register NoRegister; + class RegisterMask { private: uint64_t mask; public: - RegisterMask(uint64_t mask) : mask(mask) {} - RegisterMask() : mask(0) {} - RegisterMask(Register reg) : mask(static_cast(1) << (int8_t)reg) {} + constexpr RegisterMask(uint64_t mask) : mask(mask) {} + constexpr RegisterMask() : mask(0) {} + constexpr RegisterMask(Register reg) : mask(static_cast(1) << (int8_t)reg) {} - RegisterMask operator &(RegisterMask o) const { + constexpr RegisterMask operator &(RegisterMask o) const { return RegisterMask(mask & o.mask); } @@ -55,27 +55,31 @@ public: return *this; } - RegisterMask operator |(RegisterMask o) const { + constexpr RegisterMask operator |(RegisterMask o) const { return RegisterMask(mask | o.mask); } - bool contains(Register reg) const { + constexpr bool contains(Register reg) const { return (mask & (static_cast(1) << (int8_t)reg)) != 0; } - bool containsExactly(Register reg) const { + constexpr bool containsExactly(Register reg) const { return mask == (mask & (static_cast(1) << (int8_t)reg)); } - RegisterMask excluding(Register reg) const { + constexpr RegisterMask excluding(Register reg) const { return RegisterMask(mask & ~(static_cast(1) << (int8_t)reg)); } - explicit operator uint64_t() const { + constexpr RegisterMask including(Register reg) const { + return RegisterMask(mask | (static_cast(1) << (int8_t)reg)); + } + + constexpr explicit operator uint64_t() const { return mask; } - explicit operator bool() const { + constexpr explicit operator bool() const { return mask != 0; } @@ -132,8 +136,8 @@ class RegisterIterator { int r = index; do { index++; - } while (index < mask.limit && !(mask.mask.contains(index))); - return r; + } while (index < mask.limit && !(mask.mask.contains(Register(index)))); + return Register(r); } }; diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 5687d5b3c3..9c0a8e46f4 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -259,7 +259,7 @@ Site* pickTargetSite(Context* c, if (target.type == lir::Operand::Type::Memory) { return frameSite(c, target.index); } else { - return registerSite(c, target.index); + return registerSite(c, Register(target.index)); } } diff --git a/src/codegen/compiler/context.cpp b/src/codegen/compiler/context.cpp index c7b7a51741..17f50856ae 100644 --- a/src/codegen/compiler/context.cpp +++ b/src/codegen/compiler/context.cpp @@ -56,7 +56,7 @@ Context::Context(vm::System* system, for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) { - new (registerResources + i) RegisterResource(arch->reserved(i)); + new (registerResources + i) RegisterResource(arch->reserved(Register(i))); if (registerResources[i].reserved) { --availableGeneralRegisterCount; @@ -65,7 +65,7 @@ Context::Context(vm::System* system, for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) { - new (registerResources + i) RegisterResource(arch->reserved(i)); + new (registerResources + i) RegisterResource(arch->reserved(Register(i))); } } diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 73c612a378..a769899b0c 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -594,7 +594,7 @@ class CallEvent : public Event { ras = static_cast(returnAddressSurrogate->source) ->number; } else { - ras = Register::None; + ras = NoRegister; } Register fps; @@ -603,7 +603,7 @@ class CallEvent : public Event { fps = static_cast(framePointerSurrogate->source)->number; } else { - fps = Register::None; + fps = NoRegister; } int offset = static_cast(footprint) @@ -1505,7 +1505,7 @@ class MemoryEvent : public Event { ConstantSite* constant = findConstantSite(c, index); if (constant) { - indexRegister = Register::None; + indexRegister = NoRegister; displacement += (constant->value->value() * scale); scale = 1; } else { @@ -1513,14 +1513,14 @@ class MemoryEvent : public Event { indexRegister = static_cast(index->source)->number; } } else { - indexRegister = Register::None; + indexRegister = NoRegister; } assertT(c, base->source->type(c) == lir::Operand::Type::RegisterPair); Register baseRegister = static_cast(base->source)->number; popRead(c, this, base); if (index) { - if (c->targetInfo.pointerSize == 8 and indexRegister != Register::None) { + if (c->targetInfo.pointerSize == 8 and indexRegister != NoRegister) { apply(c, lir::Move, 4, @@ -2035,7 +2035,7 @@ class BoundsCheckEvent : public Event { assertT(c, object->source->type(c) == lir::Operand::Type::RegisterPair); MemorySite length(static_cast(object->source)->number, lengthOffset, - Register::None, + NoRegister, 1); length.acquired = true; diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 844eae6b70..b16e68dfd2 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -91,13 +91,13 @@ Register pickRegisterTarget(Context* c, unsigned* cost, CostCalculator* costCalculator) { - Register target = Register::None; + Register target = NoRegister; *cost = Target::Impossible; if (mask & c->regFile->generalRegisters.mask) { - for (Register i = c->regFile->generalRegisters.limit - 1; + for (Register i = Register(c->regFile->generalRegisters.limit - 1); (int8_t)i >= c->regFile->generalRegisters.start; - i = (int8_t)i - 1) { + i = Register((int8_t)i - 1)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } @@ -105,9 +105,9 @@ Register pickRegisterTarget(Context* c, } if (mask & c->regFile->floatRegisters.mask) { - for (Register i = c->regFile->floatRegisters.start; + for (Register i = Register(c->regFile->floatRegisters.start); (int8_t)i < c->regFile->floatRegisters.limit; - i = (int8_t)i + 1) { + i = Register((int8_t)i + 1)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } diff --git a/src/codegen/compiler/resource.cpp b/src/codegen/compiler/resource.cpp index 13f64abb8e..b0b7ad63c2 100644 --- a/src/codegen/compiler/resource.cpp +++ b/src/codegen/compiler/resource.cpp @@ -113,9 +113,9 @@ unsigned RegisterResource::toString(Context* c, return vm::snprintf(buffer, bufferSize, "register %d", index(c)); } -unsigned RegisterResource::index(Context* c) +Register RegisterResource::index(Context* c) { - return this - c->registerResources; + return Register(this - c->registerResources); } void RegisterResource::increment(Context* c) diff --git a/src/codegen/compiler/resource.h b/src/codegen/compiler/resource.h index 1712871079..5c98c5ec46 100644 --- a/src/codegen/compiler/resource.h +++ b/src/codegen/compiler/resource.h @@ -48,7 +48,7 @@ class RegisterResource : public Resource { virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize); - virtual unsigned index(Context*); + virtual Register index(Context*); void increment(Context*); diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 25810e8773..221d2add91 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -224,7 +224,7 @@ RegisterSite::RegisterSite(RegisterMask mask, Register number) unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize) { - if (number != Register::None) { + if (number != NoRegister) { return vm::snprintf(buffer, bufferSize, "%p register %d", this, number); } else { return vm::snprintf( @@ -234,7 +234,7 @@ unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize) unsigned RegisterSite::copyCost(Context* c, Site* s) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); if (s and (this == s or (s->type(c) == lir::Operand::Type::RegisterPair @@ -247,7 +247,7 @@ unsigned RegisterSite::copyCost(Context* c, Site* s) bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { return mask.registerMask.contains(number); @@ -258,7 +258,7 @@ bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { return mask.registerMask.containsExactly(number); @@ -269,7 +269,7 @@ bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); if (s->type(c) != lir::Operand::Type::RegisterPair) { return false; @@ -278,7 +278,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) RegisterSite* rs = static_cast(s); unsigned size = rs->registerSize(c); if (size > c->targetInfo.pointerSize) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); return number == rs->number; } else { RegisterMask mask = c->regFile->generalRegisters.mask; @@ -289,7 +289,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) void RegisterSite::acquire(Context* c, Value* v) { Target target; - if (number != Register::None) { + if (number != NoRegister) { target = Target(number, 0); } else { target = pickRegisterTarget(c, v, mask_); @@ -299,33 +299,33 @@ void RegisterSite::acquire(Context* c, Value* v) RegisterResource* resource = c->registerResources + target.index; compiler::acquire(c, resource, v, this); - number = target.index; + number = Register(target.index); } void RegisterSite::release(Context* c, Value* v) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); compiler::release(c, c->registerResources + (int8_t)number, v, this); } void RegisterSite::freeze(Context* c, Value* v) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); c->registerResources[(int8_t)number].freeze(c, v); } void RegisterSite::thaw(Context* c, Value* v) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); c->registerResources[(int8_t)number].thaw(c, v); } bool RegisterSite::frozen(Context* c UNUSED) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); return c->registerResources[(int8_t)number].freezeCount != 0; } @@ -339,14 +339,14 @@ void RegisterSite::asAssemblerOperand(Context* c UNUSED, Site* high, lir::Operand* result) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); Register highNumber; if (high != this) { highNumber = static_cast(high)->number; - assertT(c, highNumber != Register::None); + assertT(c, highNumber != NoRegister); } else { - highNumber = Register::None; + highNumber = NoRegister; } new (result) lir::RegisterPair(number, highNumber); @@ -356,7 +356,7 @@ Site* RegisterSite::copy(Context* c) { RegisterMask mask; - if (number != Register::None) { + if (number != NoRegister) { mask = RegisterMask(number); } else { mask = mask_; @@ -377,7 +377,7 @@ Site* RegisterSite::copyHigh(Context* c) Site* RegisterSite::makeNextWord(Context* c, unsigned) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); assertT(c, c->regFile->generalRegisters.mask.contains(number)); return freeRegisterSite(c, c->regFile->generalRegisters.mask); @@ -390,7 +390,7 @@ SiteMask RegisterSite::mask(Context* c UNUSED) SiteMask RegisterSite::nextWordMask(Context* c, unsigned) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); if (registerSize(c) > c->targetInfo.pointerSize) { return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, number, NoFrameIndex); @@ -403,7 +403,7 @@ SiteMask RegisterSite::nextWordMask(Context* c, unsigned) unsigned RegisterSite::registerSize(Context* c) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); if (c->regFile->floatRegisters.mask.contains(number)) { return c->arch->floatRegisterSize(); @@ -414,14 +414,14 @@ unsigned RegisterSite::registerSize(Context* c) RegisterMask RegisterSite::registerMask(Context* c UNUSED) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); return RegisterMask(number); } Site* registerSite(Context* c, Register number) { - assertT(c, number != Register::None); + assertT(c, number != NoRegister); assertT(c, (c->regFile->generalRegisters.mask | c->regFile->floatRegisters.mask).contains(number)); @@ -431,7 +431,7 @@ Site* registerSite(Context* c, Register number) Site* freeRegisterSite(Context* c, RegisterMask mask) { - return new (c->zone) RegisterSite(mask, Register::None); + return new (c->zone) RegisterSite(mask, NoRegister); } MemorySite::MemorySite(Register base, int offset, Register index, unsigned scale) @@ -468,7 +468,7 @@ bool MemorySite::conflicts(const SiteMask& mask) { return (mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) != 0 and (!mask.registerMask.contains(base) - or (index != Register::None + or (index != NoRegister and !mask.registerMask.contains(index))); } @@ -479,7 +479,7 @@ bool MemorySite::match(Context* c, const SiteMask& mask) if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { if (mask.frameIndex >= 0) { if (base == c->arch->stack()) { - assertT(c, index == Register::None); + assertT(c, index == NoRegister); return static_cast(frameIndexToOffset(c, mask.frameIndex)) == offset; } else { @@ -499,7 +499,7 @@ bool MemorySite::loneMatch(Context* c, const SiteMask& mask) if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { if (base == c->arch->stack()) { - assertT(c, index == Register::None); + assertT(c, index == NoRegister); if (mask.frameIndex == AnyFrameIndex) { return false; @@ -533,12 +533,12 @@ bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) void MemorySite::acquire(Context* c, Value* v) { c->registerResources[(int8_t)base].increment(c); - if (index != Register::None) { + if (index != NoRegister) { c->registerResources[(int8_t)index].increment(c); } if (base == c->arch->stack()) { - assertT(c, index == Register::None); + assertT(c, index == NoRegister); assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); compiler::acquire( @@ -551,7 +551,7 @@ void MemorySite::acquire(Context* c, Value* v) void MemorySite::release(Context* c, Value* v) { if (base == c->arch->stack()) { - assertT(c, index == Register::None); + assertT(c, index == NoRegister); assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); compiler::release( @@ -559,7 +559,7 @@ void MemorySite::release(Context* c, Value* v) } c->registerResources[(int8_t)base].decrement(c); - if (index != Register::None) { + if (index != NoRegister) { c->registerResources[(int8_t)index].decrement(c); } @@ -572,7 +572,7 @@ void MemorySite::freeze(Context* c, Value* v) c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); } else { c->registerResources[(int8_t)base].increment(c); - if (index != Register::None) { + if (index != NoRegister) { c->registerResources[(int8_t)index].increment(c); } } @@ -584,7 +584,7 @@ void MemorySite::thaw(Context* c, Value* v) c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); } else { c->registerResources[(int8_t)base].decrement(c); - if (index != Register::None) { + if (index != NoRegister) { c->registerResources[(int8_t)index].decrement(c); } } @@ -668,7 +668,7 @@ SiteMask MemorySite::nextWordMask(Context* c, unsigned index) { int frameIndex; if (base == c->arch->stack()) { - assertT(c, this->index == Register::None); + assertT(c, this->index == NoRegister); frameIndex = static_cast(offsetToFrameIndex(c, offset)) + ((index == 1) xor c->arch->bigEndian() ? 1 : -1); } else { @@ -697,7 +697,7 @@ MemorySite* frameSite(Context* c, int frameIndex) return memorySite(c, c->arch->stack(), frameIndexToOffset(c, frameIndex), - Register::None, + NoRegister, 0); } diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 64da8cd71a..88e3995af3 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -360,7 +360,7 @@ class MemorySite : public Site { MemorySite* memorySite(Context* c, Register base, int offset = 0, - Register index = Register::None, + Register index = NoRegister, unsigned scale = 1); MemorySite* frameSite(Context* c, int frameIndex); diff --git a/src/codegen/registers.cpp b/src/codegen/registers.cpp index 0df2325690..001de19df7 100644 --- a/src/codegen/registers.cpp +++ b/src/codegen/registers.cpp @@ -13,12 +13,10 @@ namespace avian { namespace codegen { -Register Register::None(-1); - unsigned BoundedRegisterMask::maskStart(RegisterMask mask) { for (int i = 0; i <= 31; ++i) { - if (mask.contains(i)) + if (mask.contains(Register(i))) return i; } return 32; @@ -27,7 +25,7 @@ unsigned BoundedRegisterMask::maskStart(RegisterMask mask) unsigned BoundedRegisterMask::maskLimit(RegisterMask mask) { for (int i = 31; i >= 0; --i) { - if (mask.contains(i)) + if (mask.contains(Register(i))) return i + 1; } return 0; diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 74ab3d6b43..bd379efa14 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -792,7 +792,7 @@ class MyAssembler : public Assembler { Register returnAddressSurrogate, Register framePointerSurrogate UNUSED) { - assertT(&con, framePointerSurrogate == Register::None); + assertT(&con, framePointerSurrogate == NoRegister); if (TailCalls) { if (offset) { @@ -813,7 +813,7 @@ class MyAssembler : public Assembler { lir::Constant footprintConstant(&footprintPromise); addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); - if (returnAddressSurrogate != Register::None) { + if (returnAddressSurrogate != NoRegister) { assertT(&con, offset > 0); lir::RegisterPair ras(returnAddressSurrogate); diff --git a/src/codegen/target/arm/operations.cpp b/src/codegen/target/arm/operations.cpp index 627d2c81d2..740c855299 100644 --- a/src/codegen/target/arm/operations.cpp +++ b/src/codegen/target/arm/operations.cpp @@ -737,7 +737,7 @@ void store(Context* con, unsigned scale, bool preserveIndex) { - if (index != Register::None) { + if (index != NoRegister) { bool release; Register normalized = normalize(con, offset, index, scale, &preserveIndex, &release); @@ -799,8 +799,8 @@ void store(Context* con, case 8: { // split into 2 32-bit stores lir::RegisterPair srcHigh(src->high); - store(con, 4, &srcHigh, base, offset, Register::None, 1, false); - store(con, 4, src, base, offset + 4, Register::None, 1, false); + store(con, 4, &srcHigh, base, offset, NoRegister, 1, false); + store(con, 4, src, base, offset + 4, NoRegister, 1, false); } break; default: @@ -853,7 +853,7 @@ void load(Context* con, bool preserveIndex, bool signExtend) { - if (index != Register::None) { + if (index != NoRegister) { bool release; Register normalized = normalize(con, offset, index, scale, &preserveIndex, &release); @@ -951,7 +951,7 @@ void load(Context* con, 4, base, offset, - Register::None, + NoRegister, 1, 4, &dstHigh, @@ -961,7 +961,7 @@ void load(Context* con, 4, base, offset + 4, - Register::None, + NoRegister, 1, 4, dst, diff --git a/src/codegen/target/arm/operations.h b/src/codegen/target/arm/operations.h index aa7492d589..1ff77d6198 100644 --- a/src/codegen/target/arm/operations.h +++ b/src/codegen/target/arm/operations.h @@ -59,9 +59,9 @@ inline lir::RegisterPair makeTemp64(Context* con) inline void freeTemp(Context* con, const lir::RegisterPair& tmp) { - if (tmp.low != Register::None) + if (tmp.low != NoRegister) freeTemp(con, tmp.low); - if (tmp.high != Register::None) + if (tmp.high != NoRegister) freeTemp(con, tmp.high); } diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index f6c4a0b87b..21a89e8362 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -205,7 +205,7 @@ class MyArchitecture : public Architecture { virtual Register returnHigh() { - return (TargetBytesPerWord == 4 ? rdx : Register::None); + return (TargetBytesPerWord == 4 ? rdx : NoRegister); } virtual Register virtualCallTarget() @@ -1070,7 +1070,7 @@ class MyAssembler : public Assembler { addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack); - if (returnAddressSurrogate != Register::None) { + if (returnAddressSurrogate != NoRegister) { assertT(&c, offset > 0); lir::RegisterPair ras(returnAddressSurrogate); @@ -1078,7 +1078,7 @@ class MyAssembler : public Assembler { moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } - if (framePointerSurrogate != Register::None) { + if (framePointerSurrogate != NoRegister) { assertT(&c, offset > 0); lir::RegisterPair fps(framePointerSurrogate); diff --git a/src/codegen/target/x86/encode.cpp b/src/codegen/target/x86/encode.cpp index fe7275a24c..16e639876a 100644 --- a/src/codegen/target/x86/encode.cpp +++ b/src/codegen/target/x86/encode.cpp @@ -65,11 +65,11 @@ void maybeRex(Context* c, } else { byte = REX_NONE; } - if (a != Register::None and ((int8_t)a & 8)) + if (a != NoRegister and ((int8_t)a & 8)) byte |= REX_R; - if (index != Register::None and ((int8_t)index & 8)) + if (index != NoRegister and ((int8_t)index & 8)) byte |= REX_X; - if (base != Register::None and ((int8_t)base & 8)) + if (base != NoRegister and ((int8_t)base & 8)) byte |= REX_B; if (always or byte != REX_NONE) c->code.append(byte); @@ -78,17 +78,17 @@ void maybeRex(Context* c, void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b) { - maybeRex(c, size, a->low, Register::None, b->low, false); + maybeRex(c, size, a->low, NoRegister, b->low, false); } void alwaysRex(Context* c, unsigned size, lir::RegisterPair* a, lir::RegisterPair* b) { - maybeRex(c, size, a->low, Register::None, b->low, true); + maybeRex(c, size, a->low, NoRegister, b->low, true); } void maybeRex(Context* c, unsigned size, lir::RegisterPair* a) { - maybeRex(c, size, Register::None, Register::None, a->low, false); + maybeRex(c, size, NoRegister, NoRegister, a->low, false); } void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b) @@ -98,7 +98,7 @@ void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b) void maybeRex(Context* c, unsigned size, lir::Memory* a) { - maybeRex(c, size, Register::None, a->index, a->base, false); + maybeRex(c, size, NoRegister, a->index, a->base, false); } void modrm(Context* c, uint8_t mod, Register a, Register b) @@ -119,7 +119,7 @@ void sib(Context* c, unsigned scale, Register index, Register base) void modrmSib(Context* c, int width, Register a, int scale, Register index, Register base) { - if (index == Register::None) { + if (index == NoRegister) { modrm(c, width, base, a); if (regCode(base) == rsp) { sib(c, 0x00, rsp, rsp); From 7c24701d3796b5e04c267cc6899bba65c5e0ca7b Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 22:06:55 -0700 Subject: [PATCH 20/70] transition x86 registers to Register instances --- include/avian/codegen/registers.h | 2 +- src/codegen/target/x86/assembler.cpp | 18 +++---- src/codegen/target/x86/operations.cpp | 2 +- src/codegen/target/x86/registers.h | 75 +++++++++++++-------------- 4 files changed, 46 insertions(+), 51 deletions(-) diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index d86b122715..89b22f6668 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -31,7 +31,7 @@ public: return !(*this == o); } - constexpr explicit operator int8_t() const { + constexpr operator int8_t() const { return index; } }; diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index 21a89e8362..ca928137f3 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -236,11 +236,11 @@ class MyArchitecture : public Architecture { virtual bool reserved(Register register_) { switch ((int8_t)register_) { - case rbp: + case (int8_t)rbp: return UseFramePointer; - case rsp: - case rbx: + case (int8_t)rsp: + case (int8_t)rbx: return true; default: @@ -602,13 +602,13 @@ class MyArchitecture : public Architecture { if (aSize == 4 and bSize == 8) { aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory); - const uint32_t mask = GeneralRegisterMask + const RegisterMask mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); aMask.setLowHighRegisterMasks(mask, mask); } else if (aSize == 1 or bSize == 1) { aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory); - const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) + const RegisterMask mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); aMask.setLowHighRegisterMasks(mask, mask); } @@ -681,7 +681,7 @@ class MyArchitecture : public Architecture { if (aSize == 4 and bSize == 8) { bMask.setLowHighRegisterMasks(1 << rax, 1 << rdx); } else if (aSize == 1 or bSize == 1) { - const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) + const RegisterMask mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); bMask.setLowHighRegisterMasks(mask, mask); } @@ -775,7 +775,7 @@ class MyArchitecture : public Architecture { case lir::Multiply: if (TargetBytesPerWord == 4 and aSize == 8) { - const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); + const RegisterMask mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); aMask.setLowHighRegisterMasks(mask, mask); bMask.setLowHighRegisterMasks(mask, 1 << rdx); } else { @@ -808,12 +808,12 @@ class MyArchitecture : public Architecture { case lir::ShiftRight: case lir::UnsignedShiftRight: { if (TargetBytesPerWord == 4 and bSize == 8) { - const uint32_t mask = GeneralRegisterMask & ~(1 << rcx); + const RegisterMask mask = GeneralRegisterMask & ~(1 << rcx); aMask.setLowHighRegisterMasks(mask, mask); bMask.setLowHighRegisterMasks(mask, mask); } else { aMask.setLowHighRegisterMasks(static_cast(1) << rcx, GeneralRegisterMask); - const uint32_t mask = GeneralRegisterMask & ~(1 << rcx); + const RegisterMask mask = GeneralRegisterMask & ~(1 << rcx); bMask.setLowHighRegisterMasks(mask, mask); } } break; diff --git a/src/codegen/target/x86/operations.cpp b/src/codegen/target/x86/operations.cpp index c61ef64477..a37b6f3f61 100644 --- a/src/codegen/target/x86/operations.cpp +++ b/src/codegen/target/x86/operations.cpp @@ -991,7 +991,7 @@ void multiplyRR(Context* c, addRR(c, 4, scratch, 4, &bh); moveRR(c, 4, &axdx, 4, b); - if (tmp.low != -1) { + if (tmp.low != NoRegister) { c->client->releaseTemporary(tmp.low); } } else { diff --git a/src/codegen/target/x86/registers.h b/src/codegen/target/x86/registers.h index b61e521b7c..79b1218b13 100644 --- a/src/codegen/target/x86/registers.h +++ b/src/codegen/target/x86/registers.h @@ -15,50 +15,45 @@ namespace avian { namespace codegen { namespace x86 { -enum { - rax = 0, - rcx = 1, - rdx = 2, - rbx = 3, - rsp = 4, - rbp = 5, - rsi = 6, - rdi = 7, - r8 = 8, - r9 = 9, - r10 = 10, - r11 = 11, - r12 = 12, - r13 = 13, - r14 = 14, - r15 = 15, -}; +constexpr Register rax((int)0); +constexpr Register rcx(1); +constexpr Register rdx(2); +constexpr Register rbx(3); +constexpr Register rsp(4); +constexpr Register rbp(5); +constexpr Register rsi(6); +constexpr Register rdi(7); +constexpr Register r8(8); +constexpr Register r9(9); +constexpr Register r10(10); +constexpr Register r11(11); +constexpr Register r12(12); +constexpr Register r13(13); +constexpr Register r14(14); +constexpr Register r15(15); +constexpr Register xmm0(16); +constexpr Register xmm1(16 + 1); +constexpr Register xmm2(16 + 2); +constexpr Register xmm3(16 + 3); +constexpr Register xmm4(16 + 4); +constexpr Register xmm5(16 + 5); +constexpr Register xmm6(16 + 6); +constexpr Register xmm7(16 + 7); +constexpr Register xmm8(16 + 8); +constexpr Register xmm9(16 + 9); +constexpr Register xmm10(16 + 10); +constexpr Register xmm11(16 + 11); +constexpr Register xmm12(16 + 12); +constexpr Register xmm13(16 + 13); +constexpr Register xmm14(16 + 14); +constexpr Register xmm15(16 + 15); -enum { - xmm0 = r15 + 1, - xmm1, - xmm2, - xmm3, - xmm4, - xmm5, - xmm6, - xmm7, - xmm8, - xmm9, - xmm10, - xmm11, - xmm12, - xmm13, - xmm14, - xmm15, -}; +constexpr Register LongJumpRegister = r10; -const int LongJumpRegister = r10; - -const unsigned GeneralRegisterMask = vm::TargetBytesPerWord == 4 ? 0x000000ff +constexpr RegisterMask GeneralRegisterMask = vm::TargetBytesPerWord == 4 ? 0x000000ff : 0x0000ffff; -const unsigned FloatRegisterMask = vm::TargetBytesPerWord == 4 ? 0x00ff0000 +constexpr RegisterMask FloatRegisterMask = vm::TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000; } // namespace x86 From 6b889b1d78e446a8e03558cea62960cff0e263fd Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Thu, 4 Dec 2014 22:15:40 -0700 Subject: [PATCH 21/70] get rid of implicit Register casts --- include/avian/codegen/registers.h | 10 ++- src/codegen/target/arm/assembler.cpp | 12 +-- src/codegen/target/arm/encode.h | 116 +++++++++++++------------- src/codegen/target/arm/operations.cpp | 8 +- src/codegen/target/arm/registers.h | 16 ++-- src/codegen/target/x86/assembler.cpp | 34 ++++---- src/codegen/target/x86/operations.cpp | 14 ++-- 7 files changed, 108 insertions(+), 102 deletions(-) diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 89b22f6668..cd3a25eaad 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -16,11 +16,13 @@ namespace avian { namespace codegen { +class RegisterMask; + class Register { private: int8_t index; public: - constexpr Register(int8_t index) : index(index) {} + explicit constexpr Register(int8_t index) : index(index) {} constexpr Register() : index(-1) {} constexpr bool operator == (Register o) const { @@ -31,6 +33,8 @@ public: return !(*this == o); } + constexpr RegisterMask operator | (Register o) const; + constexpr operator int8_t() const { return index; } @@ -87,6 +91,10 @@ public: static RegisterMask None; }; +constexpr RegisterMask Register::operator | (Register o) const { + return RegisterMask(*this) | o; +} + class BoundedRegisterMask { public: RegisterMask mask; diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index bd379efa14..3f7d2cdde5 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -166,7 +166,7 @@ class MyArchitecture : public Architecture { virtual Register scratch() { - return 5; + return Register(5); } virtual Register stack() @@ -181,22 +181,22 @@ class MyArchitecture : public Architecture { virtual Register returnLow() { - return 0; + return Register(0); } virtual Register returnHigh() { - return 1; + return Register(1); } virtual Register virtualCallTarget() { - return 4; + return Register(4); } virtual Register virtualCallIndex() { - return 3; + return Register(3); } virtual ir::TargetInfo targetInfo() @@ -265,7 +265,7 @@ class MyArchitecture : public Architecture { { assertT(&con, index < argumentRegisterCount()); - return index; + return Register(index); } virtual bool hasLinkRegister() diff --git a/src/codegen/target/arm/encode.h b/src/codegen/target/arm/encode.h index 1bbf385246..4cbe3c1cd8 100644 --- a/src/codegen/target/arm/encode.h +++ b/src/codegen/target/arm/encode.h @@ -135,11 +135,11 @@ inline int XFER2I(int cond, } inline int COOP(int cond, int opcode_1, - Register CRn, - Register CRd, + int CRn, + int CRd, int cp_num, int opcode_2, - Register CRm) + int CRm) { return cond << 28 | 0xe << 24 | opcode_1 << 20 | (int8_t)CRn << 16 | (int8_t)CRd << 12 | cp_num << 8 | opcode_2 << 5 | (int8_t)CRm; @@ -151,7 +151,7 @@ inline int COXFER(int cond, int W, int L, Register Rn, - Register CRd, + int CRd, int cp_num, int offset) // offset is in words, not bytes { @@ -161,17 +161,17 @@ inline int COXFER(int cond, inline int COREG(int cond, int opcode_1, int L, - Register CRn, + int CRn, Register Rd, int cp_num, int opcode_2, - Register CRm) + int CRm) { return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | (int8_t)CRn << 16 | (int8_t)Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | (int8_t)CRm; } inline int - COREG2(int cond, int L, Register Rn, Register Rd, int cp_num, int opcode, Register CRm) + COREG2(int cond, int L, Register Rn, Register Rd, int cp_num, int opcode, int CRm) { return cond << 28 | 0xc4 << 20 | L << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | cp_num << 8 | opcode << 4 | (int8_t)CRm; @@ -225,7 +225,7 @@ inline int rsc(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) } inline int cmp(Register Rn, Register Rm, int Sh = 0, int shift = 0) { - return DATA(AL, 0xa, 1, Rn, 0, shift, Sh, Rm); + return DATA(AL, 0xa, 1, Rn, Register(0), shift, Sh, Rm); } inline int orr(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) { @@ -233,11 +233,11 @@ inline int orr(Register Rd, Register Rn, Register Rm, int Sh = 0, int shift = 0) } inline int mov(Register Rd, Register Rm, int Sh = 0, int shift = 0) { - return DATA(AL, 0xd, 0, 0, Rd, shift, Sh, Rm); + return DATA(AL, 0xd, 0, Register(0), Rd, shift, Sh, Rm); } inline int mvn(Register Rd, Register Rm, int Sh = 0, int shift = 0) { - return DATA(AL, 0xf, 0, 0, Rd, shift, Sh, Rm); + return DATA(AL, 0xf, 0, Register(0), Rd, shift, Sh, Rm); } inline int andi(Register Rd, Register Rn, int imm, int rot = 0) { @@ -265,11 +265,11 @@ inline int bici(Register Rd, Register Rn, int imm, int rot = 0) } inline int cmpi(Register Rn, int imm, int rot = 0) { - return DATAI(AL, 0xa, 1, Rn, 0, rot, imm); + return DATAI(AL, 0xa, 1, Rn, Register(0), rot, imm); } inline int movi(Register Rd, int imm, int rot = 0) { - return DATAI(AL, 0xd, 0, 0, Rd, rot, imm); + return DATAI(AL, 0xd, 0, Register(0), Rd, rot, imm); } inline int orrsh(Register Rd, Register Rn, Register Rm, Register Rs, int Sh) { @@ -277,11 +277,11 @@ inline int orrsh(Register Rd, Register Rn, Register Rm, Register Rs, int Sh) } inline int movsh(Register Rd, Register Rm, Register Rs, int Sh) { - return DATAS(AL, 0xd, 0, 0, Rd, Rs, Sh, Rm); + return DATAS(AL, 0xd, 0, Register(0), Rd, Rs, Sh, Rm); } inline int mul(Register Rd, Register Rm, Register Rs) { - return MULTIPLY(AL, 0, 0, Rd, 0, Rs, Rm); + return MULTIPLY(AL, 0, 0, Rd, Register(0), Rs, Rm); } inline int mla(Register Rd, Register Rm, Register Rs, Register Rn) { @@ -404,31 +404,31 @@ inline int bkpt(int16_t immed) inline int mcr(int coproc, int opcode_1, Register Rd, - Register CRn, - Register CRm, + int CRn, + int CRm, int opcode_2 = 0) { return COREG(AL, opcode_1, 0, CRn, Rd, coproc, opcode_2, CRm); } -inline int mcrr(int coproc, int opcode, Register Rd, Register Rn, Register CRm) +inline int mcrr(int coproc, int opcode, Register Rd, Register Rn, int CRm) { return COREG2(AL, 0, Rn, Rd, coproc, opcode, CRm); } inline int mrc(int coproc, int opcode_1, Register Rd, - Register CRn, - Register CRm, + int CRn, + int CRm, int opcode_2 = 0) { return COREG(AL, opcode_1, 1, CRn, Rd, coproc, opcode_2, CRm); } -inline int mrrc(int coproc, int opcode, Register Rd, Register Rn, Register CRm) +inline int mrrc(int coproc, int opcode, Register Rd, Register Rn, int CRm) { return COREG2(AL, 1, Rn, Rd, coproc, opcode, CRm); } // VFP FLOATING-POINT INSTRUCTIONS -inline int fmuls(Register Sd, Register Sn, Register Sm) +inline int fmuls(int Sd, int Sn, int Sm) { return COOP(AL, ((int8_t)Sd & 1) << 2 | 2, @@ -438,7 +438,7 @@ inline int fmuls(Register Sd, Register Sn, Register Sm) ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fadds(Register Sd, Register Sn, Register Sm) +inline int fadds(int Sd, int Sn, int Sm) { return COOP(AL, ((int8_t)Sd & 1) << 2 | 3, @@ -448,7 +448,7 @@ inline int fadds(Register Sd, Register Sn, Register Sm) ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); } -inline int fsubs(Register Sd, Register Sn, Register Sm) +inline int fsubs(int Sd, int Sn, int Sm) { return COOP(AL, ((int8_t)Sd & 1) << 2 | 3, @@ -458,7 +458,7 @@ inline int fsubs(Register Sd, Register Sn, Register Sm) ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1) | 2, (int8_t)Sm >> 1); } -inline int fdivs(Register Sd, Register Sn, Register Sm) +inline int fdivs(int Sd, int Sn, int Sm) { return COOP(AL, ((int8_t)Sd & 1) << 2 | 8, @@ -484,37 +484,37 @@ inline int fdivd(int Dd, int Dn, int Dm) { return COOP(AL, 8, Dn, Dd, 11, 0, Dm); } -inline int fcpys(Register Sd, Register Sm) +inline int fcpys(int Sd, int Sm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1); } -inline int fabss(Register Sd, Register Sm) +inline int fabss(int Sd, int Sm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); } -inline int fnegs(Register Sd, Register Sm) +inline int fnegs(int Sd, int Sm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 1, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1); } -inline int fsqrts(Register Sd, Register Sm) +inline int fsqrts(int Sd, int Sm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 1, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); } -inline int fcmps(Register Sd, Register Sm) +inline int fcmps(int Sd, int Sm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 4, (int8_t)Sd >> 1, 10, 2 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb | (Sd & 1) << 2, 4, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1); } -inline int fcvtds(int Dd, Register Sm) +inline int fcvtds(int Dd, int Sm) { - return COOP(AL, 0xb, 7, Dd, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb, 7, Dd, 10, 6 | (Sm & 1), Sm >> 1); } -inline int fsitos(Register Sd, Register Sm) +inline int fsitos(int Sd, int Sm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 8, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb | (Sd & 1) << 2, 8, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); } -inline int ftosizs(Register Sd, Register Sm) +inline int ftosizs(int Sd, int Sm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0xd, (int8_t)Sd >> 1, 10, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1); } inline int fcpyd(int Dd, int Dm) { @@ -538,43 +538,43 @@ inline int fcmpd(int Dd, int Dm) return COOP(AL, 0xb, 4, Dd, 11, 2, Dm); } // double-precision conversion instructions -inline int fcvtsd(Register Sd, int Dm) +inline int fcvtsd(int Sd, int Dm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 7, (int8_t)Sd >> 1, 11, 6, Dm); + return COOP(AL, 0xb | (Sd & 1) << 2, 7, Sd >> 1, 11, 6, Dm); } -inline int fsitod(Register Dd, Register Sm) +inline int fsitod(int Dd, int Sm) { - return COOP(AL, 0xb, 8, Dd, 11, 6 | ((int8_t)Sm & 1), (int8_t)Sm >> 1); + return COOP(AL, 0xb, 8, Dd, 11, 6 | (Sm & 1), Sm >> 1); } -inline int ftosizd(Register Sd, Register Dm) +inline int ftosizd(int Sd, int Dm) { - return COOP(AL, 0xb | ((int8_t)Sd & 1) << 2, 0xd, (int8_t)Sd >> 1, 11, 6, Dm); + return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 11, 6, Dm); } // single load/store instructions for both precision types -inline int flds(Register Sd, Register Rn, int offset = 0) +inline int flds(int Sd, Register Rn, int offset = 0) { - return COXFER(AL, 1, 1, (int8_t)Sd & 1, 0, 1, Rn, (int8_t)Sd >> 1, 10, offset); + return COXFER(AL, 1, 1, Sd & 1, 0, 1, Rn, Sd >> 1, 10, offset); }; -inline int fldd(Register Dd, Register Rn, int offset = 0) +inline int fldd(int Dd, Register Rn, int offset = 0) { return COXFER(AL, 1, 1, 0, 0, 1, Rn, Dd, 11, offset); }; -inline int fsts(Register Sd, Register Rn, int offset = 0) +inline int fsts(int Sd, Register Rn, int offset = 0) { - return COXFER(AL, 1, 1, (int8_t)Sd & 1, 0, 0, Rn, (int8_t)Sd >> 1, 10, offset); + return COXFER(AL, 1, 1, Sd & 1, 0, 0, Rn, Sd >> 1, 10, offset); }; -inline int fstd(Register Dd, Register Rn, int offset = 0) +inline int fstd(int Dd, Register Rn, int offset = 0) { return COXFER(AL, 1, 1, 0, 0, 0, Rn, Dd, 11, offset); }; // move between GPRs and FPRs -inline int fmsr(Register Sn, Register Rd) +inline int fmsr(int Sn, Register Rd) { - return mcr(10, 0, Rd, (int8_t)Sn >> 1, 0, ((int8_t)Sn & 1) << 2); + return mcr(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2); } -inline int fmrs(Register Rd, Register Sn) +inline int fmrs(Register Rd, int Sn) { - return mrc(10, 0, Rd, (int8_t)Sn >> 1, 0, ((int8_t)Sn & 1) << 2); + return mrc(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2); } // move to/from VFP system registers inline int fmrx(Register Rd, int reg) @@ -582,7 +582,7 @@ inline int fmrx(Register Rd, int reg) return mrc(10, 7, Rd, reg, 0); } // these move around pairs of single-precision registers -inline int fmdrr(Register Dm, Register Rd, Register Rn) +inline int fmdrr(int Dm, Register Rd, Register Rn) { return mcrr(11, 1, Rd, Rn, Dm); } @@ -670,7 +670,7 @@ inline int bpl(int offset) } inline int fmstat() { - return fmrx(15, FPSCR); + return fmrx(Register(15), FPSCR); } // todo: make this pretty: inline int dmb() diff --git a/src/codegen/target/arm/operations.cpp b/src/codegen/target/arm/operations.cpp index 740c855299..87d88613fd 100644 --- a/src/codegen/target/arm/operations.cpp +++ b/src/codegen/target/arm/operations.cpp @@ -575,7 +575,7 @@ void float2IntRR(Context* con, lir::RegisterPair* b) { Register tmp = newTemp(con, FPR_MASK); - Register ftmp = fpr32(tmp); + int ftmp = fpr32(tmp); if (size == 8) { // double to int emit(con, ftosizd(ftmp, fpr64(a))); } else { // float to int @@ -1129,7 +1129,7 @@ void moveAR2(Context* con, lir::Constant constant(src->address); moveCR(con, srcSize, &constant, dstSize, dst); - lir::Memory memory(dst->low, 0, -1, 0); + lir::Memory memory(dst->low, 0, NoRegister, 0); moveMR(con, dstSize, &memory, dstSize, dst); } @@ -1491,7 +1491,7 @@ void longCallC(Context* con, unsigned size UNUSED, lir::Constant* target) { assertT(con, size == vm::TargetBytesPerWord); - lir::RegisterPair tmp(4); + lir::RegisterPair tmp(Register(4)); moveCR2(con, vm::TargetBytesPerWord, target, &tmp, offsetPromise(con)); callR(con, vm::TargetBytesPerWord, &tmp); } @@ -1500,7 +1500,7 @@ void longJumpC(Context* con, unsigned size UNUSED, lir::Constant* target) { assertT(con, size == vm::TargetBytesPerWord); - lir::RegisterPair tmp(4); // a non-arg reg that we don't mind clobbering + lir::RegisterPair tmp(Register(4)); // a non-arg reg that we don't mind clobbering moveCR2(con, vm::TargetBytesPerWord, target, &tmp, offsetPromise(con)); jumpR(con, vm::TargetBytesPerWord, &tmp); } diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index 900ef58019..adefa9b8cc 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -49,15 +49,15 @@ inline int fpr32(lir::RegisterPair* reg) } #ifdef ARCH_arm64 -const int ThreadRegister = 19; -const int StackRegister = 31; -const int LinkRegister = 30; -const int ProgramCounter = 0xFF; // i.e. unaddressable +constexpr Register ThreadRegister(19); +constexpr Register StackRegister(31); +constexpr Register LinkRegister(30); +constexpr Register ProgramCounter(0xFE); // i.e. unaddressable #else -const int ThreadRegister = 8; -const int StackRegister = 13; -const int LinkRegister = 14; -const int ProgramCounter = 15; +constexpr Register ThreadRegister(8); +constexpr Register StackRegister(13); +constexpr Register LinkRegister(14); +constexpr Register ProgramCounter(15); #endif } // namespace arm diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index ca928137f3..347ab0b228 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -519,13 +519,13 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Negate: aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); - aMask.setLowHighRegisterMasks(1 << rax, 1 << rdx); + aMask.setLowHighRegisterMasks(rax, rdx); break; case lir::Absolute: if (aSize <= TargetBytesPerWord) { aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); - aMask.setLowHighRegisterMasks(1 << rax, 0); + aMask.setLowHighRegisterMasks(rax, 0); } else { *thunk = true; } @@ -603,13 +603,12 @@ class MyArchitecture : public Architecture { aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory); const RegisterMask mask = GeneralRegisterMask - & ~((1 << rax) | (1 << rdx)); + .excluding(rax).excluding(rdx); aMask.setLowHighRegisterMasks(mask, mask); } else if (aSize == 1 or bSize == 1) { aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory); - const RegisterMask mask = (1 << rax) | (1 << rcx) | (1 << rdx) - | (1 << rbx); + const RegisterMask mask = rax | rcx | rdx | rbx; aMask.setLowHighRegisterMasks(mask, mask); } } @@ -632,7 +631,7 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Absolute: bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); - bMask.setLowHighRegisterMasks(1 << rax, 0); + bMask.setLowHighRegisterMasks(rax, 0); break; case lir::FloatAbsolute: @@ -679,10 +678,9 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { - bMask.setLowHighRegisterMasks(1 << rax, 1 << rdx); + bMask.setLowHighRegisterMasks(rax, rdx); } else if (aSize == 1 or bSize == 1) { - const RegisterMask mask = (1 << rax) | (1 << rcx) | (1 << rdx) - | (1 << rbx); + const RegisterMask mask = rax | rcx | rdx | rbx; bMask.setLowHighRegisterMasks(mask, mask); } } @@ -775,9 +773,9 @@ class MyArchitecture : public Architecture { case lir::Multiply: if (TargetBytesPerWord == 4 and aSize == 8) { - const RegisterMask mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); + const RegisterMask mask = GeneralRegisterMask .excluding(rax).excluding(rdx); aMask.setLowHighRegisterMasks(mask, mask); - bMask.setLowHighRegisterMasks(mask, 1 << rdx); + bMask.setLowHighRegisterMasks(mask, rdx); } else { aMask.setLowHighRegisterMasks(GeneralRegisterMask, 0); bMask.setLowHighRegisterMasks(GeneralRegisterMask, 0); @@ -789,8 +787,8 @@ class MyArchitecture : public Architecture { *thunk = true; } else { aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); - aMask.setLowHighRegisterMasks(GeneralRegisterMask & ~((1 << rax) | (1 << rdx)), 0); - bMask.setLowHighRegisterMasks(1 << rax, 0); + aMask.setLowHighRegisterMasks(GeneralRegisterMask .excluding(rax).excluding(rdx), 0); + bMask.setLowHighRegisterMasks(rax, 0); } break; @@ -799,8 +797,8 @@ class MyArchitecture : public Architecture { *thunk = true; } else { aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); - aMask.setLowHighRegisterMasks(GeneralRegisterMask & ~((1 << rax) | (1 << rdx)), 0); - bMask.setLowHighRegisterMasks(1 << rax, 0); + aMask.setLowHighRegisterMasks(GeneralRegisterMask .excluding(rax).excluding(rdx), 0); + bMask.setLowHighRegisterMasks(rax, 0); } break; @@ -808,12 +806,12 @@ class MyArchitecture : public Architecture { case lir::ShiftRight: case lir::UnsignedShiftRight: { if (TargetBytesPerWord == 4 and bSize == 8) { - const RegisterMask mask = GeneralRegisterMask & ~(1 << rcx); + const RegisterMask mask = GeneralRegisterMask.excluding(rcx); aMask.setLowHighRegisterMasks(mask, mask); bMask.setLowHighRegisterMasks(mask, mask); } else { - aMask.setLowHighRegisterMasks(static_cast(1) << rcx, GeneralRegisterMask); - const RegisterMask mask = GeneralRegisterMask & ~(1 << rcx); + aMask.setLowHighRegisterMasks(rcx, GeneralRegisterMask); + const RegisterMask mask = GeneralRegisterMask.excluding(rcx); bMask.setLowHighRegisterMasks(mask, mask); } } break; diff --git a/src/codegen/target/x86/operations.cpp b/src/codegen/target/x86/operations.cpp index a37b6f3f61..9906cc517e 100644 --- a/src/codegen/target/x86/operations.cpp +++ b/src/codegen/target/x86/operations.cpp @@ -491,7 +491,7 @@ void moveAR(Context* c, assertT(c, vm::TargetBytesPerWord == 8 or (aSize == 4 and bSize == 4)); lir::Constant constant(a->address); - lir::Memory memory(b->low, 0, -1, 0); + lir::Memory memory(b->low, 0, NoRegister, 0); moveCR(c, aSize, &constant, bSize, b); moveMR(c, bSize, &memory, bSize, b); @@ -507,7 +507,7 @@ void moveCM(Context* c, case 1: maybeRex(c, bSize, b); opcode(c, 0xc6); - modrmSibImm(c, 0, b->scale, b->index, b->base, b->offset); + modrmSibImm(c, rax, b->scale, b->index, b->base, b->offset); c->code.append(a->value->value()); break; @@ -515,14 +515,14 @@ void moveCM(Context* c, opcode(c, 0x66); maybeRex(c, bSize, b); opcode(c, 0xc7); - modrmSibImm(c, 0, b->scale, b->index, b->base, b->offset); + modrmSibImm(c, rax, b->scale, b->index, b->base, b->offset); c->code.append2(a->value->value()); break; case 4: maybeRex(c, bSize, b); opcode(c, 0xc7); - modrmSibImm(c, 0, b->scale, b->index, b->base, b->offset); + modrmSibImm(c, rax, b->scale, b->index, b->base, b->offset); if (a->value->resolved()) { c->code.append4(a->value->value()); } else { @@ -536,7 +536,7 @@ void moveCM(Context* c, if (a->value->resolved() and vm::fitsInInt32(a->value->value())) { maybeRex(c, bSize, b); opcode(c, 0xc7); - modrmSibImm(c, 0, b->scale, b->index, b->base, b->offset); + modrmSibImm(c, rax, b->scale, b->index, b->base, b->offset); c->code.append4(a->value->value()); } else { lir::RegisterPair tmp(c->client->acquireTemporary(GeneralRegisterMask)); @@ -970,10 +970,10 @@ void multiplyRR(Context* c, lir::RegisterPair ah(a->high); lir::RegisterPair bh(b->high); - lir::RegisterPair tmp(-1); + lir::RegisterPair tmp(NoRegister); lir::RegisterPair* scratch; if (a->low == b->low) { - tmp.low = c->client->acquireTemporary(GeneralRegisterMask & ~(1 << rax)); + tmp.low = c->client->acquireTemporary(GeneralRegisterMask.excluding(rax)); scratch = &tmp; moveRR(c, 4, b, 4, scratch); } else { From a3ccc94cf5477a61282a1262ffd7d874b0a38760 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Fri, 5 Dec 2014 12:27:33 -0700 Subject: [PATCH 22/70] make BoundedRegisterMask a subclass of RegisterMask --- include/avian/codegen/registers.h | 7 +++---- src/codegen/compiler.cpp | 10 +++++----- src/codegen/compiler/event.cpp | 2 +- src/codegen/compiler/regalloc.cpp | 8 ++++---- src/codegen/compiler/resource.cpp | 8 ++++---- src/codegen/compiler/site.cpp | 14 +++++++------- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index cd3a25eaad..34b74926cb 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -95,9 +95,8 @@ constexpr RegisterMask Register::operator | (Register o) const { return RegisterMask(*this) | o; } -class BoundedRegisterMask { +class BoundedRegisterMask : public RegisterMask { public: - RegisterMask mask; uint8_t start; uint8_t limit; @@ -105,7 +104,7 @@ class BoundedRegisterMask { static unsigned maskLimit(RegisterMask mask); inline BoundedRegisterMask(RegisterMask mask) - : mask(mask), start(maskStart(mask)), limit(maskLimit(mask)) + : RegisterMask(mask), start(maskStart(mask)), limit(maskLimit(mask)) { } }; @@ -144,7 +143,7 @@ class RegisterIterator { int r = index; do { index++; - } while (index < mask.limit && !(mask.mask.contains(Register(index)))); + } while (index < mask.limit && !(mask.contains(Register(index)))); return Register(r); } }; diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 9c0a8e46f4..02a1a224e9 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -515,14 +515,14 @@ void steal(Context* c, Resource* r, Value* thief) SiteMask generalRegisterMask(Context* c) { return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, - c->regFile->generalRegisters.mask, + c->regFile->generalRegisters, NoFrameIndex); } SiteMask generalRegisterOrConstantMask(Context* c) { return SiteMask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant), - c->regFile->generalRegisters.mask, + c->regFile->generalRegisters, NoFrameIndex); } @@ -874,7 +874,7 @@ void maybeMove(Context* c, c->arch->planSource(op, dstSize, src, dstSize, &thunk); if (isGeneralValue(srcValue)) { - src.lowRegisterMask &= c->regFile->generalRegisters.mask; + src.lowRegisterMask &= c->regFile->generalRegisters; } assertT(c, thunk == 0); @@ -1636,7 +1636,7 @@ bool resolveSourceSites(Context* c, if (r and sites[el.localIndex] == 0) { SiteMask mask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory), - c->regFile->generalRegisters.mask, + c->regFile->generalRegisters, AnyFrameIndex); Site* s = pickSourceSite( @@ -1678,7 +1678,7 @@ void resolveTargetSites(Context* c, if (r and sites[el.localIndex] == 0) { SiteMask mask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory), - c->regFile->generalRegisters.mask, + c->regFile->generalRegisters, AnyFrameIndex); Site* s = pickSourceSite( diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index a769899b0c..b23e4a56f6 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -372,7 +372,7 @@ class CallEvent : public Event { ? arguments.count : 0) { - RegisterMask registerMask = c->regFile->generalRegisters.mask; + RegisterMask registerMask = c->regFile->generalRegisters; if (callingConvention == ir::CallingConvention::Native) { assertT(c, (flags & Compiler::TailJump) == 0); diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index b16e68dfd2..26ce7b2b78 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -94,7 +94,7 @@ Register pickRegisterTarget(Context* c, Register target = NoRegister; *cost = Target::Impossible; - if (mask & c->regFile->generalRegisters.mask) { + if (mask & c->regFile->generalRegisters) { for (Register i = Register(c->regFile->generalRegisters.limit - 1); (int8_t)i >= c->regFile->generalRegisters.start; i = Register((int8_t)i - 1)) { @@ -104,7 +104,7 @@ Register pickRegisterTarget(Context* c, } } - if (mask & c->regFile->floatRegisters.mask) { + if (mask & c->regFile->floatRegisters) { for (Register i = Register(c->regFile->floatRegisters.start); (int8_t)i < c->regFile->floatRegisters.limit; i = Register((int8_t)i + 1)) { @@ -235,13 +235,13 @@ Target pickTarget(Context* c, Value* value = read->value; RegisterMask registerMask - = (isFloatValue(value) ? RegisterMask::Any : c->regFile->generalRegisters.mask); + = (isFloatValue(value) ? RegisterMask::Any : (RegisterMask)c->regFile->generalRegisters); SiteMask mask(~0, registerMask, AnyFrameIndex); read->intersect(&mask); if (isFloatValue(value)) { - RegisterMask floatMask = mask.registerMask & c->regFile->floatRegisters.mask; + RegisterMask floatMask = mask.registerMask & c->regFile->floatRegisters; if (floatMask) { mask.registerMask = floatMask; } diff --git a/src/codegen/compiler/resource.cpp b/src/codegen/compiler/resource.cpp index b0b7ad63c2..915da9ccff 100644 --- a/src/codegen/compiler/resource.cpp +++ b/src/codegen/compiler/resource.cpp @@ -88,7 +88,7 @@ void RegisterResource::freeze(Context* c, Value* v) freezeResource(c, this, v); if (freezeCount == 1 - and c->regFile->generalRegisters.mask.contains(index(c))) { + and c->regFile->generalRegisters.contains(index(c))) { decrementAvailableGeneralRegisterCount(c); } } @@ -100,7 +100,7 @@ void RegisterResource::thaw(Context* c, Value* v) thawResource(c, this, v); if (freezeCount == 0 - and c->regFile->generalRegisters.mask.contains(index(c))) { + and c->regFile->generalRegisters.contains(index(c))) { incrementAvailableGeneralRegisterCount(c); } } @@ -130,7 +130,7 @@ void RegisterResource::increment(Context* c) ++this->referenceCount; if (this->referenceCount == 1 - and c->regFile->generalRegisters.mask.contains(this->index(c))) { + and c->regFile->generalRegisters.contains(this->index(c))) { decrementAvailableGeneralRegisterCount(c); } } @@ -150,7 +150,7 @@ void RegisterResource::decrement(Context* c) --this->referenceCount; if (this->referenceCount == 0 - and c->regFile->generalRegisters.mask.contains(this->index(c))) { + and c->regFile->generalRegisters.contains(this->index(c))) { incrementAvailableGeneralRegisterCount(c); } } diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 221d2add91..ca9ba2ff97 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -281,7 +281,7 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) assertT(c, number != NoRegister); return number == rs->number; } else { - RegisterMask mask = c->regFile->generalRegisters.mask; + RegisterMask mask = c->regFile->generalRegisters; return mask.contains(number) and mask.contains(rs->number); } } @@ -378,9 +378,9 @@ Site* RegisterSite::copyHigh(Context* c) Site* RegisterSite::makeNextWord(Context* c, unsigned) { assertT(c, number != NoRegister); - assertT(c, c->regFile->generalRegisters.mask.contains(number)); + assertT(c, c->regFile->generalRegisters.contains(number)); - return freeRegisterSite(c, c->regFile->generalRegisters.mask); + return freeRegisterSite(c, c->regFile->generalRegisters); } SiteMask RegisterSite::mask(Context* c UNUSED) @@ -396,7 +396,7 @@ SiteMask RegisterSite::nextWordMask(Context* c, unsigned) return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, number, NoFrameIndex); } else { return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, - c->regFile->generalRegisters.mask, + c->regFile->generalRegisters, NoFrameIndex); } } @@ -405,7 +405,7 @@ unsigned RegisterSite::registerSize(Context* c) { assertT(c, number != NoRegister); - if (c->regFile->floatRegisters.mask.contains(number)) { + if (c->regFile->floatRegisters.contains(number)) { return c->arch->floatRegisterSize(); } else { return c->targetInfo.pointerSize; @@ -423,8 +423,8 @@ Site* registerSite(Context* c, Register number) { assertT(c, number != NoRegister); assertT(c, - (c->regFile->generalRegisters.mask - | c->regFile->floatRegisters.mask).contains(number)); + (c->regFile->generalRegisters + | c->regFile->floatRegisters).contains(number)); return new (c->zone) RegisterSite(RegisterMask(number), number); } From 08f524a1065bf26792f5ae061d94d2ba7a70f932 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Fri, 5 Dec 2014 16:04:39 -0700 Subject: [PATCH 23/70] add convenience (1 << lir::Operand::Type::*) shortcuts (lir::Operand::*Mask) --- include/avian/codegen/lir.h | 5 ++ src/codegen/compiler.cpp | 14 ++-- src/codegen/compiler/event.cpp | 16 ++--- src/codegen/compiler/read.cpp | 2 +- src/codegen/compiler/regalloc.cpp | 8 +-- src/codegen/compiler/site.cpp | 24 +++---- src/codegen/compiler/site.h | 8 +-- src/codegen/target/arm/assembler.cpp | 50 ++++++------- src/codegen/target/x86/assembler.cpp | 102 +++++++++++++-------------- 9 files changed, 117 insertions(+), 112 deletions(-) diff --git a/include/avian/codegen/lir.h b/include/avian/codegen/lir.h index 08c0fb3ee0..de90239b45 100644 --- a/include/avian/codegen/lir.h +++ b/include/avian/codegen/lir.h @@ -129,6 +129,11 @@ public: }; const static unsigned TypeCount = (unsigned)Type::Memory + 1; + + const static unsigned ConstantMask = 1 << (unsigned)Type::Constant; + const static unsigned AddressMask = 1 << (unsigned)Type::Address; + const static unsigned RegisterPairMask = 1 << (unsigned)Type::RegisterPair; + const static unsigned MemoryMask = 1 << (unsigned)Type::Memory; }; class Constant : public Operand { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 02a1a224e9..a5baccc155 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -514,14 +514,14 @@ void steal(Context* c, Resource* r, Value* thief) SiteMask generalRegisterMask(Context* c) { - return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, + return SiteMask(lir::Operand::RegisterPairMask, c->regFile->generalRegisters, NoFrameIndex); } SiteMask generalRegisterOrConstantMask(Context* c) { - return SiteMask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant), + return SiteMask(lir::Operand::RegisterPairMask | lir::Operand::ConstantMask, c->regFile->generalRegisters, NoFrameIndex); } @@ -620,7 +620,7 @@ bool acceptForResolve(Context* c, Site* s, Read* read, const SiteMask& mask) return c->availableGeneralRegisterCount > ResolveRegisterReserveCount; } else { assertT(c, - s->match(c, SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, AnyFrameIndex))); + s->match(c, SiteMask(lir::Operand::MemoryMask, 0, AnyFrameIndex))); return isHome(read->value, offsetToFrameIndex(c, static_cast(s)->offset)); @@ -782,7 +782,7 @@ void saveLocals(Context* c, Event* e) e->addRead( c, local->value, - SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, compiler::frameIndex(c, li))); + SiteMask(lir::Operand::MemoryMask, 0, compiler::frameIndex(c, li))); } } } @@ -878,7 +878,7 @@ void maybeMove(Context* c, } assertT(c, thunk == 0); - assertT(c, dstMask.typeMask & src.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)); + assertT(c, dstMask.typeMask & src.typeMask & lir::Operand::RegisterPairMask); Site* tmpTarget = freeRegisterSite(c, dstMask.registerMask & src.lowRegisterMask); @@ -1635,7 +1635,7 @@ bool resolveSourceSites(Context* c, Read* r = live(c, v); if (r and sites[el.localIndex] == 0) { - SiteMask mask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory), + SiteMask mask(lir::Operand::RegisterPairMask | lir::Operand::MemoryMask, c->regFile->generalRegisters, AnyFrameIndex); @@ -1677,7 +1677,7 @@ void resolveTargetSites(Context* c, Read* r = live(c, v); if (r and sites[el.localIndex] == 0) { - SiteMask mask((1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory), + SiteMask mask(lir::Operand::RegisterPairMask | lir::Operand::MemoryMask, c->regFile->generalRegisters, AnyFrameIndex); diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index b23e4a56f6..a0356c6de8 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -415,7 +415,7 @@ class CallEvent : public Event { fprintf(stderr, "stack %d arg read %p\n", frameIndex, v); } - targetMask = SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex); + targetMask = SiteMask(lir::Operand::MemoryMask, 0, frameIndex); } this->addRead(c, v, targetMask); @@ -512,7 +512,7 @@ class CallEvent : public Event { this->addRead(c, v, generalRegisterMask(c)); } else { this->addRead( - c, v, SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex)); + c, v, SiteMask(lir::Operand::MemoryMask, 0, frameIndex)); } } } @@ -544,7 +544,7 @@ class CallEvent : public Event { this->addRead(c, stack->value, - SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, logicalIndex)); + SiteMask(lir::Operand::MemoryMask, 0, logicalIndex)); } stack = stack->next; @@ -866,7 +866,7 @@ class MoveEvent : public Event { assertT(c, srcSelectSize == c->targetInfo.pointerSize); if (dstValue->nextWord->target or live(c, dstValue->nextWord)) { - assertT(c, dstLowMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)); + assertT(c, dstLowMask.typeMask & lir::Operand::RegisterPairMask); Site* low = freeRegisterSite(c, dstLowMask.registerMask); @@ -897,7 +897,7 @@ class MoveEvent : public Event { srcValue->source->thaw(c, srcValue); - assertT(c, dstHighMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)); + assertT(c, dstHighMask.typeMask & lir::Operand::RegisterPairMask); Site* high = freeRegisterSite(c, dstHighMask.registerMask); @@ -1461,7 +1461,7 @@ ConstantSite* findConstantSite(Context* c, Value* v) void moveIfConflict(Context* c, Value* v, MemorySite* s) { if (v->reads) { - SiteMask mask(1 << (unsigned)lir::Operand::Type::RegisterPair, ~0, AnyFrameIndex); + SiteMask mask(lir::Operand::RegisterPairMask, ~0, AnyFrameIndex); v->reads->intersect(&mask); if (s->conflicts(mask)) { maybeMove(c, v->reads, true, false); @@ -1873,12 +1873,12 @@ void clean(Context* c, Value* v, unsigned popIndex) { for (SiteIterator it(c, v); it.hasMore();) { Site* s = it.next(); - if (not(s->match(c, SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, AnyFrameIndex)) + if (not(s->match(c, SiteMask(lir::Operand::MemoryMask, 0, AnyFrameIndex)) and offsetToFrameIndex(c, static_cast(s)->offset) >= popIndex)) { if (false and s->match(c, - SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, AnyFrameIndex))) { + SiteMask(lir::Operand::MemoryMask, 0, AnyFrameIndex))) { char buffer[256]; s->toString(c, buffer, 256); fprintf(stderr, diff --git a/src/codegen/compiler/read.cpp b/src/codegen/compiler/read.cpp index d9909ed343..d734caf358 100644 --- a/src/codegen/compiler/read.cpp +++ b/src/codegen/compiler/read.cpp @@ -205,7 +205,7 @@ Read* StubRead::next(Context*) SingleRead* read(Context* c, const SiteMask& mask, Value* successor) { assertT(c, - (mask.typeMask != 1 << (unsigned)lir::Operand::Type::Memory) or mask.frameIndex >= 0); + (mask.typeMask != lir::Operand::MemoryMask) or mask.frameIndex >= 0); return new (c->zone) SingleRead(mask, successor); } diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 26ce7b2b78..15143e2b48 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -71,7 +71,7 @@ bool pickRegisterTarget(Context* c, c, v, r, - SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, RegisterMask(i), NoFrameIndex), + SiteMask(lir::Operand::RegisterPairMask, RegisterMask(i), NoFrameIndex), costCalculator) + Target::MinimumRegisterCost; if (mask.containsExactly(i)) { @@ -135,7 +135,7 @@ unsigned frameCost(Context* c, return resourceCost(c, v, c->frameResources + frameIndex, - SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex), + SiteMask(lir::Operand::MemoryMask, 0, frameIndex), costCalculator) + Target::MinimumFrameCost; } @@ -186,7 +186,7 @@ Target pickTarget(Context* c, Target best, CostCalculator* costCalculator) { - if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) { + if (mask.typeMask & lir::Operand::RegisterPairMask) { Target mine = pickRegisterTarget(c, value, mask.registerMask, costCalculator); @@ -198,7 +198,7 @@ Target pickTarget(Context* c, } } - if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { + if (mask.typeMask & lir::Operand::MemoryMask) { if (mask.frameIndex >= 0) { Target mine(mask.frameIndex, lir::Operand::Type::Memory, diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index ca9ba2ff97..17d99e60d8 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -152,7 +152,7 @@ class AddressSite : public Site { virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << (unsigned)lir::Operand::Type::Address); + return mask.typeMask & lir::Operand::AddressMask; } virtual bool loneMatch(Context*, const SiteMask&) @@ -201,7 +201,7 @@ class AddressSite : public Site { virtual SiteMask mask(Context*) { - return SiteMask(1 << (unsigned)lir::Operand::Type::Address, 0, NoFrameIndex); + return SiteMask(lir::Operand::AddressMask, 0, NoFrameIndex); } virtual SiteMask nextWordMask(Context* c, unsigned) @@ -249,7 +249,7 @@ bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) { assertT(c, number != NoRegister); - if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { + if ((mask.typeMask & lir::Operand::RegisterPairMask)) { return mask.registerMask.contains(number); } else { return false; @@ -260,7 +260,7 @@ bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) { assertT(c, number != NoRegister); - if ((mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair))) { + if ((mask.typeMask & lir::Operand::RegisterPairMask)) { return mask.registerMask.containsExactly(number); } else { return false; @@ -385,7 +385,7 @@ Site* RegisterSite::makeNextWord(Context* c, unsigned) SiteMask RegisterSite::mask(Context* c UNUSED) { - return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, mask_, NoFrameIndex); + return SiteMask(lir::Operand::RegisterPairMask, mask_, NoFrameIndex); } SiteMask RegisterSite::nextWordMask(Context* c, unsigned) @@ -393,9 +393,9 @@ SiteMask RegisterSite::nextWordMask(Context* c, unsigned) assertT(c, number != NoRegister); if (registerSize(c) > c->targetInfo.pointerSize) { - return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, number, NoFrameIndex); + return SiteMask(lir::Operand::RegisterPairMask, number, NoFrameIndex); } else { - return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, + return SiteMask(lir::Operand::RegisterPairMask, c->regFile->generalRegisters, NoFrameIndex); } @@ -466,7 +466,7 @@ unsigned MemorySite::copyCost(Context* c, Site* s) bool MemorySite::conflicts(const SiteMask& mask) { - return (mask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) != 0 + return (mask.typeMask & lir::Operand::RegisterPairMask) != 0 and (!mask.registerMask.contains(base) or (index != NoRegister and !mask.registerMask.contains(index))); @@ -476,7 +476,7 @@ bool MemorySite::match(Context* c, const SiteMask& mask) { assertT(c, acquired); - if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { + if (mask.typeMask & lir::Operand::MemoryMask) { if (mask.frameIndex >= 0) { if (base == c->arch->stack()) { assertT(c, index == NoRegister); @@ -497,7 +497,7 @@ bool MemorySite::loneMatch(Context* c, const SiteMask& mask) { assertT(c, acquired); - if (mask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { + if (mask.typeMask & lir::Operand::MemoryMask) { if (base == c->arch->stack()) { assertT(c, index == NoRegister); @@ -657,7 +657,7 @@ Site* MemorySite::makeNextWord(Context* c, unsigned index) SiteMask MemorySite::mask(Context* c) { - return SiteMask(1 << (unsigned)lir::Operand::Type::Memory, + return SiteMask(lir::Operand::MemoryMask, 0, (base == c->arch->stack()) ? static_cast(offsetToFrameIndex(c, offset)) @@ -674,7 +674,7 @@ SiteMask MemorySite::nextWordMask(Context* c, unsigned index) } else { frameIndex = NoFrameIndex; } - return SiteMask(1 << (unsigned)lir::Operand::Type::Memory, 0, frameIndex); + return SiteMask(lir::Operand::MemoryMask, 0, frameIndex); } bool MemorySite::isVolatile(Context* c) diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 88e3995af3..f18a54009c 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -43,7 +43,7 @@ class SiteMask { static SiteMask fixedRegisterMask(Register number) { - return SiteMask(1 << (unsigned)lir::Operand::Type::RegisterPair, 1 << (int8_t)number, NoFrameIndex); + return SiteMask(lir::Operand::RegisterPairMask, 1 << (int8_t)number, NoFrameIndex); } static SiteMask lowPart(const OperandMask& mask) @@ -187,7 +187,7 @@ class ConstantSite : public Site { virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << (unsigned)lir::Operand::Type::Constant); + return mask.typeMask & lir::Operand::ConstantMask; } virtual bool loneMatch(Context*, const SiteMask&) @@ -236,12 +236,12 @@ class ConstantSite : public Site { virtual SiteMask mask(Context*) { - return SiteMask(1 << (unsigned)lir::Operand::Type::Constant, 0, NoFrameIndex); + return SiteMask(lir::Operand::ConstantMask, 0, NoFrameIndex); } virtual SiteMask nextWordMask(Context*, unsigned) { - return SiteMask(1 << (unsigned)lir::Operand::Type::Constant, 0, NoFrameIndex); + return SiteMask(lir::Operand::ConstantMask, 0, NoFrameIndex); } Promise* value; diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 3f7d2cdde5..f4a3192656 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -396,7 +396,7 @@ class MyArchitecture : public Architecture { OperandMask& aMask, bool* thunk) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant); + aMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::ConstantMask; aMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); *thunk = false; } @@ -413,7 +413,7 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Negate: - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; @@ -426,7 +426,7 @@ class MyArchitecture : public Architecture { case lir::FloatNegate: case lir::Float2Float: if (vfpSupported()) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); } else { *thunk = true; @@ -439,7 +439,7 @@ class MyArchitecture : public Architecture { // thunks or produce inline machine code which handles edge // cases properly. if (false && vfpSupported() && bSize == 4) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); } else { *thunk = true; @@ -448,7 +448,7 @@ class MyArchitecture : public Architecture { case lir::Int2Float: if (vfpSupported() && aSize == 4) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); } else { *thunk = true; @@ -466,12 +466,12 @@ class MyArchitecture : public Architecture { unsigned, OperandMask& bMask) { - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory); + bMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::MemoryMask; bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); switch (op) { case lir::Negate: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; @@ -480,18 +480,18 @@ class MyArchitecture : public Architecture { case lir::FloatNegate: case lir::Float2Float: case lir::Int2Float: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); break; case lir::Float2Int: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); break; case lir::Move: - if (!(aMask.typeMask & 1 << (unsigned)lir::Operand::Type::RegisterPair)) { - bMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; + if (!(aMask.typeMask & lir::Operand::RegisterPairMask)) { + bMask.typeMask = lir::Operand::RegisterPairMask; } break; @@ -511,15 +511,15 @@ class MyArchitecture : public Architecture { tmpMask.typeMask = 0; tmpMask.setLowHighRegisterMasks(0, 0); - if (dstMask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { + if (dstMask.typeMask & lir::Operand::MemoryMask) { // can't move directly from memory or constant to memory - srcMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; - tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; + srcMask.typeMask = lir::Operand::RegisterPairMask; + tmpMask.typeMask = lir::Operand::RegisterPairMask; tmpMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); - } else if (vfpSupported() && dstMask.typeMask & 1 << (unsigned)lir::Operand::Type::RegisterPair + } else if (vfpSupported() && dstMask.typeMask & lir::Operand::RegisterPairMask && dstMask.lowRegisterMask & FPR_MASK) { - srcMask.typeMask = tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair - | 1 << (unsigned)lir::Operand::Type::Memory; + srcMask.typeMask = tmpMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; tmpMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); } } @@ -532,10 +532,10 @@ class MyArchitecture : public Architecture { unsigned, bool* thunk) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant); + aMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::ConstantMask; aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); *thunk = false; @@ -545,7 +545,7 @@ class MyArchitecture : public Architecture { case lir::ShiftRight: case lir::UnsignedShiftRight: if (bSize == 8) - aMask.typeMask = bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = bMask.typeMask = lir::Operand::RegisterPairMask; break; case lir::Add: @@ -553,7 +553,7 @@ class MyArchitecture : public Architecture { case lir::Or: case lir::Xor: case lir::Multiply: - aMask.typeMask = bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = bMask.typeMask = lir::Operand::RegisterPairMask; break; case lir::Divide: @@ -567,7 +567,7 @@ class MyArchitecture : public Architecture { case lir::FloatMultiply: case lir::FloatDivide: if (vfpSupported()) { - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); bMask = aMask; } else { @@ -586,7 +586,7 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatLessOrEqualOrUnordered: case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (vfpSupported()) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); bMask = aMask; } else { @@ -608,10 +608,10 @@ class MyArchitecture : public Architecture { OperandMask& cMask) { if (isBranch(op)) { - cMask.typeMask = (1 << (unsigned)lir::Operand::Type::Constant); + cMask.typeMask = lir::Operand::ConstantMask; cMask.setLowHighRegisterMasks(0, 0); } else { - cMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + cMask.typeMask = lir::Operand::RegisterPairMask; cMask.lowRegisterMask = bMask.lowRegisterMask; cMask.highRegisterMask = bMask.highRegisterMask; } diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index 347ab0b228..ead5765075 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -501,8 +501,8 @@ class MyArchitecture : public Architecture { OperandMask& aMask, bool* thunk) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Memory) - | (1 << (unsigned)lir::Operand::Type::Constant); + aMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::MemoryMask + | lir::Operand::ConstantMask; *thunk = false; } @@ -518,13 +518,13 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Negate: - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(rax, rdx); break; case lir::Absolute: if (aSize <= TargetBytesPerWord) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(rax, 0); } else { *thunk = true; @@ -533,7 +533,7 @@ class MyArchitecture : public Architecture { case lir::FloatAbsolute: if (useSSE(&c)) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -543,7 +543,7 @@ class MyArchitecture : public Architecture { case lir::FloatNegate: // floatNegateRR does not support doubles if (useSSE(&c) and aSize == 4 and bSize == 4) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FloatRegisterMask, 0); } else { *thunk = true; @@ -552,8 +552,8 @@ class MyArchitecture : public Architecture { case lir::FloatSquareRoot: if (useSSE(&c)) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + aMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -562,8 +562,8 @@ class MyArchitecture : public Architecture { case lir::Float2Float: if (useSSE(&c)) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + aMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -576,8 +576,8 @@ class MyArchitecture : public Architecture { // thunks or produce inline machine code which handles edge // cases properly. if (false and useSSE(&c) and bSize <= TargetBytesPerWord) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + aMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); } else { *thunk = true; @@ -586,8 +586,8 @@ class MyArchitecture : public Architecture { case lir::Int2Float: if (useSSE(&c) and aSize <= TargetBytesPerWord) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + aMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; aMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } else { *thunk = true; @@ -600,14 +600,14 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + aMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; const RegisterMask mask = GeneralRegisterMask .excluding(rax).excluding(rdx); aMask.setLowHighRegisterMasks(mask, mask); } else if (aSize == 1 or bSize == 1) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + aMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; const RegisterMask mask = rax | rcx | rdx | rbx; aMask.setLowHighRegisterMasks(mask, mask); } @@ -630,18 +630,18 @@ class MyArchitecture : public Architecture { switch (op) { case lir::Absolute: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(rax, 0); break; case lir::FloatAbsolute: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.lowRegisterMask = aMask.lowRegisterMask; bMask.highRegisterMask = aMask.highRegisterMask; break; case lir::Negate: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.lowRegisterMask = aMask.lowRegisterMask; bMask.highRegisterMask = aMask.highRegisterMask; break; @@ -650,30 +650,30 @@ class MyArchitecture : public Architecture { case lir::FloatSquareRoot: case lir::Float2Float: case lir::Int2Float: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); break; case lir::Float2Int: - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; break; case lir::Move: if (aMask.typeMask - & ((1 << (unsigned)lir::Operand::Type::Memory) | 1 << (unsigned)lir::Operand::Type::Address)) { - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + & (lir::Operand::MemoryMask | lir::Operand::AddressMask)) { + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(GeneralRegisterMask | FloatRegisterMask, GeneralRegisterMask); - } else if (aMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) { - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + } else if (aMask.typeMask & lir::Operand::RegisterPairMask) { + bMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; if (aMask.lowRegisterMask & FloatRegisterMask) { bMask.setLowHighRegisterMasks(FloatRegisterMask, 0); } else { bMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } } else { - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + bMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; } if (TargetBytesPerWord == 4) { @@ -702,32 +702,32 @@ class MyArchitecture : public Architecture { tmpMask.typeMask = 0; tmpMask.setLowHighRegisterMasks(0, 0); - if (dstMask.typeMask & (1 << (unsigned)lir::Operand::Type::Memory)) { + if (dstMask.typeMask & lir::Operand::MemoryMask) { // can't move directly from memory to memory - srcMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Constant); - tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::RegisterPair; + srcMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::ConstantMask; + tmpMask.typeMask = lir::Operand::RegisterPairMask; tmpMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); - } else if (dstMask.typeMask & (1 << (unsigned)lir::Operand::Type::RegisterPair)) { + } else if (dstMask.typeMask & lir::Operand::RegisterPairMask) { if (size > TargetBytesPerWord) { // can't move directly from FPR to GPR or vice-versa for // values larger than the GPR size if (dstMask.lowRegisterMask & FloatRegisterMask) { srcMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); - tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::Memory; + tmpMask.typeMask = lir::Operand::MemoryMask; } else if (dstMask.lowRegisterMask & GeneralRegisterMask) { srcMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); - tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::Memory; + tmpMask.typeMask = lir::Operand::MemoryMask; } } if (dstMask.lowRegisterMask & FloatRegisterMask) { // can't move directly from constant to FPR - srcMask.typeMask &= ~(1 << (unsigned)lir::Operand::Type::Constant); + srcMask.typeMask &= ~lir::Operand::ConstantMask; if (size > TargetBytesPerWord) { - tmpMask.typeMask = 1 << (unsigned)lir::Operand::Type::Memory; + tmpMask.typeMask = lir::Operand::MemoryMask; } else { - tmpMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); + tmpMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; tmpMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); } } @@ -742,10 +742,10 @@ class MyArchitecture : public Architecture { unsigned, bool* thunk) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) | (1 << (unsigned)lir::Operand::Type::Constant); + aMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::ConstantMask; aMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + bMask.typeMask = lir::Operand::RegisterPairMask; bMask.setLowHighRegisterMasks(GeneralRegisterMask, GeneralRegisterMask); *thunk = false; @@ -756,9 +756,9 @@ class MyArchitecture : public Architecture { case lir::FloatMultiply: case lir::FloatDivide: if (useSSE(&c)) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair) - | (1 << (unsigned)lir::Operand::Type::Memory); - bMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask + | lir::Operand::MemoryMask; + bMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); bMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); @@ -786,7 +786,7 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(GeneralRegisterMask .excluding(rax).excluding(rdx), 0); bMask.setLowHighRegisterMasks(rax, 0); } @@ -796,7 +796,7 @@ class MyArchitecture : public Architecture { if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(GeneralRegisterMask .excluding(rax).excluding(rdx), 0); bMask.setLowHighRegisterMasks(rax, 0); } @@ -827,7 +827,7 @@ class MyArchitecture : public Architecture { case lir::JumpIfFloatLessOrEqualOrUnordered: case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (useSSE(&c)) { - aMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FloatRegisterMask, FloatRegisterMask); bMask.typeMask = aMask.typeMask; bMask.lowRegisterMask = aMask.lowRegisterMask; @@ -851,10 +851,10 @@ class MyArchitecture : public Architecture { OperandMask& cMask) { if (isBranch(op)) { - cMask.typeMask = (1 << (unsigned)lir::Operand::Type::Constant); + cMask.typeMask = lir::Operand::ConstantMask; cMask.setLowHighRegisterMasks(0, 0); } else { - cMask.typeMask = (1 << (unsigned)lir::Operand::Type::RegisterPair); + cMask.typeMask = lir::Operand::RegisterPairMask; cMask.lowRegisterMask = bMask.lowRegisterMask; cMask.highRegisterMask = bMask.highRegisterMask; } From d4045629d76f89712f97b9080d732556a7ba0bed Mon Sep 17 00:00:00 2001 From: "joshuawarner32@gmail.com" Date: Fri, 5 Dec 2014 19:22:44 -0700 Subject: [PATCH 24/70] Remove unnecessary (int8_t) casts in arm backend --- src/codegen/target/arm/encode.h | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/codegen/target/arm/encode.h b/src/codegen/target/arm/encode.h index 4cbe3c1cd8..d7e7b82926 100644 --- a/src/codegen/target/arm/encode.h +++ b/src/codegen/target/arm/encode.h @@ -141,8 +141,8 @@ inline int COOP(int cond, int opcode_2, int CRm) { - return cond << 28 | 0xe << 24 | opcode_1 << 20 | (int8_t)CRn << 16 | (int8_t)CRd << 12 - | cp_num << 8 | opcode_2 << 5 | (int8_t)CRm; + return cond << 28 | 0xe << 24 | opcode_1 << 20 | CRn << 16 | CRd << 12 + | cp_num << 8 | opcode_2 << 5 | CRm; } inline int COXFER(int cond, int P, @@ -156,7 +156,7 @@ inline int COXFER(int cond, int offset) // offset is in words, not bytes { return cond << 28 | 0x6 << 25 | P << 24 | U << 23 | N << 22 | W << 21 - | L << 20 | (int8_t)Rn << 16 | (int8_t)CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; + | L << 20 | (int8_t)Rn << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; } inline int COREG(int cond, int opcode_1, @@ -167,14 +167,14 @@ inline int COREG(int cond, int opcode_2, int CRm) { - return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | (int8_t)CRn << 16 - | (int8_t)Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | (int8_t)CRm; + return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | CRn << 16 + | (int8_t)Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm; } inline int COREG2(int cond, int L, Register Rn, Register Rd, int cp_num, int opcode, int CRm) { return cond << 28 | 0xc4 << 20 | L << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | cp_num << 8 - | opcode << 4 | (int8_t)CRm; + | opcode << 4 | CRm; } // FIELD CALCULATORS inline int calcU(int imm) @@ -431,42 +431,42 @@ inline int mrrc(int coproc, int opcode, Register Rd, Register Rn, int CRm) inline int fmuls(int Sd, int Sn, int Sm) { return COOP(AL, - ((int8_t)Sd & 1) << 2 | 2, - (int8_t)Sn >> 1, - (int8_t)Sd >> 1, + (Sd & 1) << 2 | 2, + Sn >> 1, + Sd >> 1, 10, - ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), - (int8_t)Sm >> 1); + (Sn & 1) << 2 | (Sm & 1), + Sm >> 1); } inline int fadds(int Sd, int Sn, int Sm) { return COOP(AL, - ((int8_t)Sd & 1) << 2 | 3, - (int8_t)Sn >> 1, - (int8_t)Sd >> 1, + (Sd & 1) << 2 | 3, + Sn >> 1, + Sd >> 1, 10, - ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), - (int8_t)Sm >> 1); + (Sn & 1) << 2 | (Sm & 1), + Sm >> 1); } inline int fsubs(int Sd, int Sn, int Sm) { return COOP(AL, - ((int8_t)Sd & 1) << 2 | 3, - (int8_t)Sn >> 1, - (int8_t)Sd >> 1, + (Sd & 1) << 2 | 3, + Sn >> 1, + Sd >> 1, 10, - ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1) | 2, - (int8_t)Sm >> 1); + (Sn & 1) << 2 | (Sm & 1) | 2, + Sm >> 1); } inline int fdivs(int Sd, int Sn, int Sm) { return COOP(AL, - ((int8_t)Sd & 1) << 2 | 8, - (int8_t)Sn >> 1, - (int8_t)Sd >> 1, + (Sd & 1) << 2 | 8, + Sn >> 1, + Sd >> 1, 10, - ((int8_t)Sn & 1) << 2 | ((int8_t)Sm & 1), - (int8_t)Sm >> 1); + (Sn & 1) << 2 | (Sm & 1), + Sm >> 1); } inline int fmuld(int Dd, int Dn, int Dm) { From a749ba7adc2b8f137477204f412854397902d0d7 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Mon, 8 Dec 2014 16:55:08 -0700 Subject: [PATCH 25/70] replace (int8_t)Register cast with Register::index() --- include/avian/codegen/registers.h | 38 +++++++++++++++++++-------- src/codegen/compiler.cpp | 6 ++--- src/codegen/compiler/event.cpp | 2 +- src/codegen/compiler/regalloc.cpp | 10 +++---- src/codegen/compiler/regalloc.h | 2 +- src/codegen/compiler/site.cpp | 24 ++++++++--------- src/codegen/compiler/site.h | 2 +- src/codegen/target/arm/assembler.cpp | 10 +++---- src/codegen/target/arm/encode.h | 34 ++++++++++++------------ src/codegen/target/arm/registers.h | 4 +-- src/codegen/target/x86/assembler.cpp | 8 +++--- src/codegen/target/x86/encode.cpp | 12 ++++----- src/codegen/target/x86/encode.h | 4 +-- src/codegen/target/x86/operations.cpp | 18 ++++++------- unittest/codegen/registers-test.cpp | 8 +++--- 15 files changed, 99 insertions(+), 83 deletions(-) diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 34b74926cb..cc91b458a5 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -20,13 +20,13 @@ class RegisterMask; class Register { private: - int8_t index; + int8_t _index; public: - explicit constexpr Register(int8_t index) : index(index) {} - constexpr Register() : index(-1) {} + explicit constexpr Register(int8_t _index) : _index(_index) {} + constexpr Register() : _index(-1) {} constexpr bool operator == (Register o) const { - return index == o.index; + return _index == o._index; } constexpr bool operator != (Register o) const { @@ -35,8 +35,24 @@ public: constexpr RegisterMask operator | (Register o) const; - constexpr operator int8_t() const { - return index; + constexpr bool operator < (Register o) const { + return _index < o._index; + } + + constexpr bool operator > (Register o) const { + return _index > o._index; + } + + constexpr bool operator <= (Register o) const { + return _index <= o._index; + } + + constexpr bool operator >= (Register o) const { + return _index >= o._index; + } + + constexpr int index() const { + return _index; } }; @@ -48,7 +64,7 @@ private: public: constexpr RegisterMask(uint64_t mask) : mask(mask) {} constexpr RegisterMask() : mask(0) {} - constexpr RegisterMask(Register reg) : mask(static_cast(1) << (int8_t)reg) {} + constexpr RegisterMask(Register reg) : mask(static_cast(1) << reg.index()) {} constexpr RegisterMask operator &(RegisterMask o) const { return RegisterMask(mask & o.mask); @@ -64,19 +80,19 @@ public: } constexpr bool contains(Register reg) const { - return (mask & (static_cast(1) << (int8_t)reg)) != 0; + return (mask & (static_cast(1) << reg.index())) != 0; } constexpr bool containsExactly(Register reg) const { - return mask == (mask & (static_cast(1) << (int8_t)reg)); + return mask == (mask & (static_cast(1) << reg.index())); } constexpr RegisterMask excluding(Register reg) const { - return RegisterMask(mask & ~(static_cast(1) << (int8_t)reg)); + return RegisterMask(mask & ~(static_cast(1) << reg.index())); } constexpr RegisterMask including(Register reg) const { - return RegisterMask(mask | (static_cast(1) << (int8_t)reg)); + return RegisterMask(mask | (static_cast(1) << reg.index())); } constexpr explicit operator uint64_t() const { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index a5baccc155..389d57c3c4 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -2216,18 +2216,18 @@ class Client : public Assembler::Client { Register r = pickRegisterTarget(c, 0, mask, &cost); expect(c, cost < Target::Impossible); save(r); - c->registerResources[(int8_t)r].increment(c); + c->registerResources[r.index()].increment(c); return r; } virtual void releaseTemporary(Register r) { - c->registerResources[(int8_t)r].decrement(c); + c->registerResources[r.index()].decrement(c); } virtual void save(Register r) { - RegisterResource* reg = c->registerResources + (int8_t)r; + RegisterResource* reg = c->registerResources + r.index(); assertT(c, reg->referenceCount == 0); assertT(c, reg->freezeCount == 0); diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index a0356c6de8..936c787e30 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -399,7 +399,7 @@ class CallEvent : public Event { Register number = c->arch->argumentRegister(index); if (DebugReads) { - fprintf(stderr, "reg %d arg read %p\n", (int8_t)number, v); + fprintf(stderr, "reg %d arg read %p\n", number.index(), v); } targetMask = SiteMask::fixedRegisterMask(number); diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 15143e2b48..13197c6b50 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -65,7 +65,7 @@ bool pickRegisterTarget(Context* c, CostCalculator* costCalculator) { if (mask.contains(i)) { - RegisterResource* r = c->registerResources + (int8_t)i; + RegisterResource* r = c->registerResources + i.index(); unsigned myCost = resourceCost( c, @@ -96,8 +96,8 @@ Register pickRegisterTarget(Context* c, if (mask & c->regFile->generalRegisters) { for (Register i = Register(c->regFile->generalRegisters.limit - 1); - (int8_t)i >= c->regFile->generalRegisters.start; - i = Register((int8_t)i - 1)) { + i.index() >= c->regFile->generalRegisters.start; + i = Register(i.index() - 1)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } @@ -106,8 +106,8 @@ Register pickRegisterTarget(Context* c, if (mask & c->regFile->floatRegisters) { for (Register i = Register(c->regFile->floatRegisters.start); - (int8_t)i < c->regFile->floatRegisters.limit; - i = Register((int8_t)i + 1)) { + i.index() < c->regFile->floatRegisters.limit; + i = Register(i.index() + 1)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } diff --git a/src/codegen/compiler/regalloc.h b/src/codegen/compiler/regalloc.h index c10105fb9d..b9b76fac8d 100644 --- a/src/codegen/compiler/regalloc.h +++ b/src/codegen/compiler/regalloc.h @@ -61,7 +61,7 @@ class Target { } Target(Register reg, unsigned cost) - : index((int8_t)reg), type(lir::Operand::Type::RegisterPair), cost(cost) + : index(reg.index()), type(lir::Operand::Type::RegisterPair), cost(cost) { } diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 17d99e60d8..745804fd65 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -306,28 +306,28 @@ void RegisterSite::release(Context* c, Value* v) { assertT(c, number != NoRegister); - compiler::release(c, c->registerResources + (int8_t)number, v, this); + compiler::release(c, c->registerResources + number.index(), v, this); } void RegisterSite::freeze(Context* c, Value* v) { assertT(c, number != NoRegister); - c->registerResources[(int8_t)number].freeze(c, v); + c->registerResources[number.index()].freeze(c, v); } void RegisterSite::thaw(Context* c, Value* v) { assertT(c, number != NoRegister); - c->registerResources[(int8_t)number].thaw(c, v); + c->registerResources[number.index()].thaw(c, v); } bool RegisterSite::frozen(Context* c UNUSED) { assertT(c, number != NoRegister); - return c->registerResources[(int8_t)number].freezeCount != 0; + return c->registerResources[number.index()].freezeCount != 0; } lir::Operand::Type RegisterSite::type(Context*) @@ -532,9 +532,9 @@ bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) void MemorySite::acquire(Context* c, Value* v) { - c->registerResources[(int8_t)base].increment(c); + c->registerResources[base.index()].increment(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].increment(c); + c->registerResources[index.index()].increment(c); } if (base == c->arch->stack()) { @@ -558,9 +558,9 @@ void MemorySite::release(Context* c, Value* v) c, c->frameResources + offsetToFrameIndex(c, offset), v, this); } - c->registerResources[(int8_t)base].decrement(c); + c->registerResources[base.index()].decrement(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].decrement(c); + c->registerResources[index.index()].decrement(c); } acquired = false; @@ -571,9 +571,9 @@ void MemorySite::freeze(Context* c, Value* v) if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); } else { - c->registerResources[(int8_t)base].increment(c); + c->registerResources[base.index()].increment(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].increment(c); + c->registerResources[index.index()].increment(c); } } } @@ -583,9 +583,9 @@ void MemorySite::thaw(Context* c, Value* v) if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); } else { - c->registerResources[(int8_t)base].decrement(c); + c->registerResources[base.index()].decrement(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].decrement(c); + c->registerResources[index.index()].decrement(c); } } } diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index f18a54009c..b2c10ddc39 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -43,7 +43,7 @@ class SiteMask { static SiteMask fixedRegisterMask(Register number) { - return SiteMask(lir::Operand::RegisterPairMask, 1 << (int8_t)number, NoFrameIndex); + return SiteMask(lir::Operand::RegisterPairMask, 1 << number.index(), NoFrameIndex); } static SiteMask lowPart(const OperandMask& mask) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index f4a3192656..2fd89a86db 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -216,11 +216,11 @@ class MyArchitecture : public Architecture { virtual bool reserved(Register register_) { - switch ((int8_t)register_) { - case LinkRegister: - case StackRegister: - case ThreadRegister: - case ProgramCounter: + switch (register_.index()) { + case LinkRegister.index(): + case StackRegister.index(): + case ThreadRegister.index(): + case ProgramCounter.index(): return true; default: diff --git a/src/codegen/target/arm/encode.h b/src/codegen/target/arm/encode.h index d7e7b82926..2ac2809157 100644 --- a/src/codegen/target/arm/encode.h +++ b/src/codegen/target/arm/encode.h @@ -48,18 +48,18 @@ enum SHIFTOP { LSL, LSR, ASR, ROR }; inline int DATA(int cond, int opcode, int S, Register Rn, Register Rd, int shift, int Sh, Register Rm) { - return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7 - | Sh << 5 | (int8_t)Rm; + return cond << 28 | opcode << 21 | S << 20 | Rn.index() << 16 | Rd.index() << 12 | shift << 7 + | Sh << 5 | Rm.index(); } inline int DATAS(int cond, int opcode, int S, Register Rn, Register Rd, Register Rs, int Sh, Register Rm) { - return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | (int8_t)Rs << 8 - | Sh << 5 | 1 << 4 | (int8_t)Rm; + return cond << 28 | opcode << 21 | S << 20 | Rn.index() << 16 | Rd.index() << 12 | Rs.index() << 8 + | Sh << 5 | 1 << 4 | Rm.index(); } inline int DATAI(int cond, int opcode, int S, Register Rn, Register Rd, int rot, int imm) { - return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 + return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | Rn.index() << 16 | Rd.index() << 12 | rot << 8 | (imm & 0xff); } inline int BRANCH(int cond, int L, int offset) @@ -68,12 +68,12 @@ inline int BRANCH(int cond, int L, int offset) } inline int BRANCHX(int cond, int L, Register Rm) { - return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | (int8_t)Rm; + return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | Rm.index(); } inline int MULTIPLY(int cond, int mul, int S, Register Rd, Register Rn, Register Rs, Register Rm) { - return cond << 28 | mul << 21 | S << 20 | (int8_t)Rd << 16 | (int8_t)Rn << 12 | (int8_t)Rs << 8 - | 9 << 4 | (int8_t)Rm; + return cond << 28 | mul << 21 | S << 20 | Rd.index() << 16 | Rn.index() << 12 | Rs.index() << 8 + | 9 << 4 | Rm.index(); } inline int XFER(int cond, int P, @@ -88,7 +88,7 @@ inline int XFER(int cond, Register Rm) { return cond << 28 | 3 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20 - | (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7 | Sh << 5 | (int8_t)Rm; + | Rn.index() << 16 | Rd.index() << 12 | shift << 7 | Sh << 5 | Rm.index(); } inline int XFERI(int cond, int P, @@ -101,7 +101,7 @@ inline int XFERI(int cond, int offset) { return cond << 28 | 2 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20 - | (int8_t)Rn << 16 | (int8_t)Rd << 12 | (offset & 0xfff); + | Rn.index() << 16 | Rd.index() << 12 | (offset & 0xfff); } inline int XFER2(int cond, int P, @@ -114,8 +114,8 @@ inline int XFER2(int cond, int H, Register Rm) { - return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | (int8_t)Rn << 16 - | (int8_t)Rd << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | (int8_t)Rm; + return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | Rn.index() << 16 + | Rd.index() << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | Rm.index(); } inline int XFER2I(int cond, int P, @@ -129,8 +129,8 @@ inline int XFER2I(int cond, int H, int offsetL) { - return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | (int8_t)Rn << 16 - | (int8_t)Rd << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4 + return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | Rn.index() << 16 + | Rd.index() << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | (offsetL & 0xf); } inline int COOP(int cond, @@ -156,7 +156,7 @@ inline int COXFER(int cond, int offset) // offset is in words, not bytes { return cond << 28 | 0x6 << 25 | P << 24 | U << 23 | N << 22 | W << 21 - | L << 20 | (int8_t)Rn << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; + | L << 20 | Rn.index() << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; } inline int COREG(int cond, int opcode_1, @@ -168,12 +168,12 @@ inline int COREG(int cond, int CRm) { return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | CRn << 16 - | (int8_t)Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm; + | Rd.index() << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm; } inline int COREG2(int cond, int L, Register Rn, Register Rd, int cp_num, int opcode, int CRm) { - return cond << 28 | 0xc4 << 20 | L << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | cp_num << 8 + return cond << 28 | 0xc4 << 20 | L << 20 | Rn.index() << 16 | Rd.index() << 12 | cp_num << 8 | opcode << 4 | CRm; } // FIELD CALCULATORS diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index adefa9b8cc..ad13db466a 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -28,12 +28,12 @@ const RegisterMask FPR_MASK = 0xffff0000; inline bool isFpr(lir::RegisterPair* reg) { - return (int8_t)reg->low >= N_GPRS; + return reg->low.index() >= N_GPRS; } inline int fpr64(Register reg) { - return (int8_t)reg - N_GPRS; + return reg.index() - N_GPRS; } inline int fpr64(lir::RegisterPair* reg) { diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index ead5765075..e78300f709 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -235,12 +235,12 @@ class MyArchitecture : public Architecture { virtual bool reserved(Register register_) { - switch ((int8_t)register_) { - case (int8_t)rbp: + switch (register_.index()) { + case rbp.index(): return UseFramePointer; - case (int8_t)rsp: - case (int8_t)rbx: + case rsp.index(): + case rbx.index(): return true; default: diff --git a/src/codegen/target/x86/encode.cpp b/src/codegen/target/x86/encode.cpp index 16e639876a..35525f5e1c 100644 --- a/src/codegen/target/x86/encode.cpp +++ b/src/codegen/target/x86/encode.cpp @@ -65,11 +65,11 @@ void maybeRex(Context* c, } else { byte = REX_NONE; } - if (a != NoRegister and ((int8_t)a & 8)) + if (a != NoRegister and (a.index() & 8)) byte |= REX_R; - if (index != NoRegister and ((int8_t)index & 8)) + if (index != NoRegister and (index.index() & 8)) byte |= REX_X; - if (base != NoRegister and ((int8_t)base & 8)) + if (base != NoRegister and (base.index() & 8)) byte |= REX_B; if (always or byte != REX_NONE) c->code.append(byte); @@ -93,7 +93,7 @@ void maybeRex(Context* c, unsigned size, lir::RegisterPair* a) void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b) { - maybeRex(c, size, a->low, b->index, b->base, size == 1 and ((int8_t)a->low & 4)); + maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low.index() & 4)); } void maybeRex(Context* c, unsigned size, lir::Memory* a) @@ -121,7 +121,7 @@ void modrmSib(Context* c, int width, Register a, int scale, Register index, Regi { if (index == NoRegister) { modrm(c, width, base, a); - if (regCode(base) == rsp) { + if (regCode(base) == rsp.index()) { sib(c, 0x00, rsp, rsp); } } else { @@ -132,7 +132,7 @@ void modrmSib(Context* c, int width, Register a, int scale, Register index, Regi void modrmSibImm(Context* c, Register a, int scale, Register index, Register base, int offset) { - if (offset == 0 and regCode(base) != rbp) { + if (offset == 0 and regCode(base) != rbp.index()) { modrmSib(c, 0x00, a, scale, index, base); } else if (vm::fitsInInt8(offset)) { modrmSib(c, 0x40, a, scale, index, base); diff --git a/src/codegen/target/x86/encode.h b/src/codegen/target/x86/encode.h index 4e5f0e6c0c..c89af512cf 100644 --- a/src/codegen/target/x86/encode.h +++ b/src/codegen/target/x86/encode.h @@ -44,7 +44,7 @@ void maybeRex(Context* c, unsigned size, lir::Memory* a); inline int regCode(Register a) { - return (int8_t)a & 7; + return a.index() & 7; } inline int regCode(lir::RegisterPair* a) @@ -54,7 +54,7 @@ inline int regCode(lir::RegisterPair* a) inline bool isFloatReg(lir::RegisterPair* a) { - return (int8_t)a->low >= xmm0; + return a->low >= xmm0; } void modrm(Context* c, uint8_t mod, Register a, Register b); diff --git a/src/codegen/target/x86/operations.cpp b/src/codegen/target/x86/operations.cpp index 9906cc517e..f936be8d3d 100644 --- a/src/codegen/target/x86/operations.cpp +++ b/src/codegen/target/x86/operations.cpp @@ -308,8 +308,8 @@ void moveRR(Context* c, } else { switch (aSize) { case 1: - if (vm::TargetBytesPerWord == 4 and (int8_t)a->low > rbx) { - assertT(c, (int8_t)b->low <= rbx); + if (vm::TargetBytesPerWord == 4 and a->low > rbx) { + assertT(c, b->low <= rbx); moveRR(c, vm::TargetBytesPerWord, a, vm::TargetBytesPerWord, b); moveRR(c, 1, b, vm::TargetBytesPerWord, b); @@ -986,7 +986,7 @@ void multiplyRR(Context* c, addRR(c, 4, &bh, 4, scratch); // mul a->low,%eax%edx - opcode(c, 0xf7, 0xe0 + (int8_t)a->low); + opcode(c, 0xf7, 0xe0 + a->low.index()); addRR(c, 4, scratch, 4, &bh); moveRR(c, 4, &axdx, 4, b); @@ -1274,7 +1274,7 @@ void multiplyCR(Context* c, assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { - const RegisterMask mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); + const RegisterMask mask = GeneralRegisterMask.excluding(rax).excluding(rdx); lir::RegisterPair tmp(c->client->acquireTemporary(mask), c->client->acquireTemporary(mask)); @@ -1403,7 +1403,7 @@ void shiftLeftRR(Context* c, modrm(c, 0xc0, b->high, b->low); // shl - opcode(c, 0xd3, 0xe0 + (int8_t)b->low); + opcode(c, 0xd3, 0xe0 + b->low.index()); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1454,7 +1454,7 @@ void shiftRightRR(Context* c, modrm(c, 0xc0, b->low, b->high); // sar - opcode(c, 0xd3, 0xf8 + (int8_t)b->high); + opcode(c, 0xd3, 0xf8 + b->high.index()); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1468,7 +1468,7 @@ void shiftRightRR(Context* c, moveRR(c, 4, &bh, 4, b); // 2 bytes // sar 31,high - opcode(c, 0xc1, 0xf8 + (int8_t)b->high); + opcode(c, 0xc1, 0xf8 + b->high.index()); c->code.append(31); } else { assertT(c, a->low == rcx); @@ -1508,7 +1508,7 @@ void unsignedShiftRightRR(Context* c, modrm(c, 0xc0, b->low, b->high); // shr - opcode(c, 0xd3, 0xe8 + (int8_t)b->high); + opcode(c, 0xd3, 0xe8 + b->high.index()); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1746,7 +1746,7 @@ void absoluteRR(Context* c, lir::RegisterPair* b UNUSED) { assertT(c, aSize == bSize and a->low == rax and b->low == rax); - lir::RegisterPair d(c->client->acquireTemporary(static_cast(1) << rdx)); + lir::RegisterPair d(c->client->acquireTemporary(rdx)); maybeRex(c, aSize, a, b); opcode(c, 0x99); xorRR(c, aSize, &d, aSize, a); diff --git a/unittest/codegen/registers-test.cpp b/unittest/codegen/registers-test.cpp index c7e9ec8d42..b648ef6e13 100644 --- a/unittest/codegen/registers-test.cpp +++ b/unittest/codegen/registers-test.cpp @@ -25,12 +25,12 @@ TEST(RegisterIterator) RegisterIterator it(regs); assertTrue(it.hasNext()); - assertEqual(0, (int8_t)it.next()); + assertEqual(0, it.next().index()); assertTrue(it.hasNext()); - assertEqual(2, (int8_t)it.next()); + assertEqual(2, it.next().index()); assertTrue(it.hasNext()); - assertEqual(4, (int8_t)it.next()); + assertEqual(4, it.next().index()); assertTrue(it.hasNext()); - assertEqual(6, (int8_t)it.next()); + assertEqual(6, it.next().index()); assertFalse(it.hasNext()); } From 01de3d9d5c86d6ba4723115f5394bd3000ce3257 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 9 Dec 2014 10:45:35 -0700 Subject: [PATCH 26/70] remove lingering 32-count limits on registers, refactor iteration, improve constants, ... --- include/avian/codegen/architecture.h | 2 +- include/avian/codegen/assembler.h | 2 +- include/avian/codegen/registers.h | 102 ++++++++++++++++++--------- makefile | 1 - src/codegen/CMakeLists.txt | 1 - src/codegen/compiler/context.cpp | 14 ++-- src/codegen/compiler/regalloc.cpp | 10 +-- src/codegen/registers.cpp | 37 ---------- src/codegen/target/arm/assembler.cpp | 6 +- src/codegen/target/x86/assembler.cpp | 4 +- unittest/codegen/registers-test.cpp | 31 +++++--- 11 files changed, 104 insertions(+), 106 deletions(-) delete mode 100644 src/codegen/registers.cpp diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index 5500311446..47687aefaf 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -45,7 +45,7 @@ class OperandMask { { } - OperandMask() : typeMask(~0), lowRegisterMask(RegisterMask::Any), highRegisterMask(RegisterMask::Any) + OperandMask() : typeMask(~0), lowRegisterMask(AnyRegisterMask), highRegisterMask(AnyRegisterMask) { } diff --git a/include/avian/codegen/assembler.h b/include/avian/codegen/assembler.h index d7be61c326..e1d451a8a9 100644 --- a/include/avian/codegen/assembler.h +++ b/include/avian/codegen/assembler.h @@ -53,7 +53,7 @@ class Assembler { public: class Client { public: - virtual Register acquireTemporary(RegisterMask mask = RegisterMask::Any) = 0; + virtual Register acquireTemporary(RegisterMask mask = AnyRegisterMask) = 0; virtual void releaseTemporary(Register r) = 0; virtual void save(Register r) = 0; diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index cc91b458a5..5cafcc724c 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -61,11 +61,27 @@ constexpr Register NoRegister; class RegisterMask { private: uint64_t mask; + + static constexpr unsigned maskStart(uint64_t mask, unsigned offset = 64) { + return mask == 0 ? (offset & 63) : maskStart(mask << 1, offset - 1); + } + + static constexpr unsigned maskLimit(uint64_t mask, unsigned offset = 0) { + return mask == 0 ? offset : maskLimit(mask >> 1, offset + 1); + } public: constexpr RegisterMask(uint64_t mask) : mask(mask) {} constexpr RegisterMask() : mask(0) {} constexpr RegisterMask(Register reg) : mask(static_cast(1) << reg.index()) {} + constexpr unsigned begin() const { + return maskStart(mask); + } + + constexpr unsigned end() const { + return maskLimit(mask); + } + constexpr RegisterMask operator &(RegisterMask o) const { return RegisterMask(mask & o.mask); } @@ -102,36 +118,79 @@ public: constexpr explicit operator bool() const { return mask != 0; } - - static RegisterMask Any; - static RegisterMask None; }; +constexpr RegisterMask AnyRegisterMask(~static_cast(0)); +constexpr RegisterMask NoneRegisterMask(0); + constexpr RegisterMask Register::operator | (Register o) const { return RegisterMask(*this) | o; } +class RegisterIterator; + class BoundedRegisterMask : public RegisterMask { public: uint8_t start; uint8_t limit; - static unsigned maskStart(RegisterMask mask); - static unsigned maskLimit(RegisterMask mask); - - inline BoundedRegisterMask(RegisterMask mask) - : RegisterMask(mask), start(maskStart(mask)), limit(maskLimit(mask)) + BoundedRegisterMask(RegisterMask mask) + : RegisterMask(mask), start(mask.begin()), limit(mask.end()) { } + + RegisterIterator begin() const; + + RegisterIterator end() const; }; +class RegisterIterator { + public: + int index; + int direction; + int limit; + const RegisterMask mask; + + RegisterIterator(int index, int direction, int limit, RegisterMask mask) + : index(index), direction(direction), limit(limit), mask(mask) + { + } + + bool operator !=(const RegisterIterator& o) const { + return index != o.index; + } + + Register operator *() { + return Register(index); + } + + void operator ++ () { + if(index != limit) { + index += direction; + } + while(index != limit && !mask.contains(Register(index))) { + index += direction; + } + } +}; + +inline RegisterIterator BoundedRegisterMask::begin() const { + // We use reverse iteration... for some reason. + return RegisterIterator(limit - 1, -1, start - 1, *this); +} + +inline RegisterIterator BoundedRegisterMask::end() const { + // We use reverse iteration... for some reason. + return RegisterIterator(start - 1, -1, start - 1, *this); +} + class RegisterFile { public: BoundedRegisterMask allRegisters; BoundedRegisterMask generalRegisters; BoundedRegisterMask floatRegisters; - inline RegisterFile(RegisterMask generalRegisterMask, RegisterMask floatRegisterMask) + RegisterFile(RegisterMask generalRegisterMask, RegisterMask floatRegisterMask) : allRegisters(generalRegisterMask | floatRegisterMask), generalRegisters(generalRegisterMask), floatRegisters(floatRegisterMask) @@ -139,31 +198,6 @@ class RegisterFile { } }; -class RegisterIterator { - public: - int index; - const BoundedRegisterMask& mask; - - inline RegisterIterator(const BoundedRegisterMask& mask) - : index(mask.start), mask(mask) - { - } - - inline bool hasNext() - { - return index < mask.limit; - } - - inline Register next() - { - int r = index; - do { - index++; - } while (index < mask.limit && !(mask.contains(Register(index)))); - return Register(r); - } -}; - } // namespace codegen } // namespace avian diff --git a/makefile b/makefile index cbaa4ec42a..73efef11ca 100755 --- a/makefile +++ b/makefile @@ -1223,7 +1223,6 @@ compiler-sources = \ $(src)/codegen/compiler.cpp \ $(wildcard $(src)/codegen/compiler/*.cpp) \ $(src)/debug-util.cpp \ - $(src)/codegen/registers.cpp \ $(src)/codegen/runtime.cpp \ $(src)/codegen/targets.cpp \ $(src)/util/fixed-allocator.cpp diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt index 8a0b4baaf2..001a8681d3 100644 --- a/src/codegen/CMakeLists.txt +++ b/src/codegen/CMakeLists.txt @@ -1,6 +1,5 @@ add_library (avian_codegen compiler.cpp - registers.cpp runtime.cpp targets.cpp diff --git a/src/codegen/compiler/context.cpp b/src/codegen/compiler/context.cpp index 17f50856ae..d285f0c77f 100644 --- a/src/codegen/compiler/context.cpp +++ b/src/codegen/compiler/context.cpp @@ -53,19 +53,15 @@ Context::Context(vm::System* system, - regFile->generalRegisters.start), targetInfo(arch->targetInfo()) { - for (unsigned i = regFile->generalRegisters.start; - i < regFile->generalRegisters.limit; - ++i) { - new (registerResources + i) RegisterResource(arch->reserved(Register(i))); + for (Register i : regFile->generalRegisters) { + new (registerResources + i.index()) RegisterResource(arch->reserved(i)); - if (registerResources[i].reserved) { + if (registerResources[i.index()].reserved) { --availableGeneralRegisterCount; } } - for (unsigned i = regFile->floatRegisters.start; - i < regFile->floatRegisters.limit; - ++i) { - new (registerResources + i) RegisterResource(arch->reserved(Register(i))); + for (Register i : regFile->floatRegisters) { + new (registerResources + i.index()) RegisterResource(arch->reserved(i)); } } diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 13197c6b50..1aed5fda70 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -95,9 +95,7 @@ Register pickRegisterTarget(Context* c, *cost = Target::Impossible; if (mask & c->regFile->generalRegisters) { - for (Register i = Register(c->regFile->generalRegisters.limit - 1); - i.index() >= c->regFile->generalRegisters.start; - i = Register(i.index() - 1)) { + for (Register i : c->regFile->generalRegisters) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } @@ -105,9 +103,7 @@ Register pickRegisterTarget(Context* c, } if (mask & c->regFile->floatRegisters) { - for (Register i = Register(c->regFile->floatRegisters.start); - i.index() < c->regFile->floatRegisters.limit; - i = Register(i.index() + 1)) { + for (Register i : c->regFile->floatRegisters) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } @@ -235,7 +231,7 @@ Target pickTarget(Context* c, Value* value = read->value; RegisterMask registerMask - = (isFloatValue(value) ? RegisterMask::Any : (RegisterMask)c->regFile->generalRegisters); + = (isFloatValue(value) ? AnyRegisterMask : (RegisterMask)c->regFile->generalRegisters); SiteMask mask(~0, registerMask, AnyFrameIndex); read->intersect(&mask); diff --git a/src/codegen/registers.cpp b/src/codegen/registers.cpp deleted file mode 100644 index 001de19df7..0000000000 --- a/src/codegen/registers.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2008-2014, Avian Contributors - - Permission to use, copy, modify, and/or distribute this software - for any purpose with or without fee is hereby granted, provided - that the above copyright notice and this permission notice appear - in all copies. - - There is NO WARRANTY for this software. See license.txt for - details. */ - -#include - -namespace avian { -namespace codegen { - -unsigned BoundedRegisterMask::maskStart(RegisterMask mask) -{ - for (int i = 0; i <= 31; ++i) { - if (mask.contains(Register(i))) - return i; - } - return 32; -} - -unsigned BoundedRegisterMask::maskLimit(RegisterMask mask) -{ - for (int i = 31; i >= 0; --i) { - if (mask.contains(Register(i))) - return i + 1; - } - return 0; -} - -RegisterMask RegisterMask::Any(~static_cast(0)); - -} // namespace codegen -} // namespace avian diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 2fd89a86db..a6c7491279 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -397,7 +397,7 @@ class MyArchitecture : public Architecture { bool* thunk) { aMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::ConstantMask; - aMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); + aMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask); *thunk = false; } @@ -506,7 +506,7 @@ class MyArchitecture : public Architecture { const OperandMask& dstMask) { srcMask.typeMask = ~0; - srcMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); + srcMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask); tmpMask.typeMask = 0; tmpMask.setLowHighRegisterMasks(0, 0); @@ -520,7 +520,7 @@ class MyArchitecture : public Architecture { && dstMask.lowRegisterMask & FPR_MASK) { srcMask.typeMask = tmpMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::MemoryMask; - tmpMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); + tmpMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask); } } diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index e78300f709..86736faa99 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -596,7 +596,7 @@ class MyArchitecture : public Architecture { case lir::Move: aMask.typeMask = ~0; - aMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); + aMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask); if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { @@ -697,7 +697,7 @@ class MyArchitecture : public Architecture { const OperandMask& dstMask) { srcMask.typeMask = ~0; - srcMask.setLowHighRegisterMasks(~static_cast(0), ~static_cast(0)); + srcMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask); tmpMask.typeMask = 0; tmpMask.setLowHighRegisterMasks(0, 0); diff --git a/unittest/codegen/registers-test.cpp b/unittest/codegen/registers-test.cpp index b648ef6e13..861a1e76c3 100644 --- a/unittest/codegen/registers-test.cpp +++ b/unittest/codegen/registers-test.cpp @@ -23,14 +23,25 @@ TEST(RegisterIterator) assertEqual(0, regs.start); assertEqual(7, regs.limit); - RegisterIterator it(regs); - assertTrue(it.hasNext()); - assertEqual(0, it.next().index()); - assertTrue(it.hasNext()); - assertEqual(2, it.next().index()); - assertTrue(it.hasNext()); - assertEqual(4, it.next().index()); - assertTrue(it.hasNext()); - assertEqual(6, it.next().index()); - assertFalse(it.hasNext()); + for(int i = 0; i < 64; i++) { + assertEqual(i, BoundedRegisterMask(static_cast(1) << i).start); + assertEqual(i + 1, BoundedRegisterMask(static_cast(1) << i).limit); + } + + auto it = regs.begin(); + auto end = regs.end(); + + assertTrue(it != end); + assertEqual(6, (*it).index()); + ++it; + assertTrue(it != end); + assertEqual(4, (*it).index()); + ++it; + assertTrue(it != end); + assertEqual(2, (*it).index()); + ++it; + assertTrue(it != end); + assertEqual(0, (*it).index()); + ++it; + assertFalse(it != end); } From 8f797e9b4ccd7da7d5926d9e40d770e4fe23929d Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 9 Dec 2014 11:47:36 -0700 Subject: [PATCH 27/70] add non-member begin/end methods for older compilers --- include/avian/codegen/registers.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 5cafcc724c..366fbde2f2 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -184,6 +184,14 @@ inline RegisterIterator BoundedRegisterMask::end() const { return RegisterIterator(start - 1, -1, start - 1, *this); } +inline RegisterIterator begin(BoundedRegisterMask mask) { + return mask.begin(); +} + +inline RegisterIterator end(BoundedRegisterMask mask) { + return mask.end(); +} + class RegisterFile { public: BoundedRegisterMask allRegisters; From 5e0f7590d9f09e0beed51f969b9cb5702fcc6f13 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 9 Dec 2014 14:44:28 -0700 Subject: [PATCH 28/70] fix process=interpret build for 'arch=arm64 platform=ios' --- makefile | 6 +++--- src/arm.S | 8 ++++---- src/avian/arm.h | 4 ++++ src/tools/object-writer/mach-o.cpp | 7 +++++++ 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/makefile b/makefile index 73efef11ca..791fa4d765 100755 --- a/makefile +++ b/makefile @@ -81,13 +81,13 @@ endif ifeq ($(platform),macosx) ifneq ($(filter arm arm64,$(arch)),) - x := $(error "please use 'arch=arm' or 'arch=arm64' 'platform=ios' to build for ios-arm") + x := $(error "please use ('arch=arm' or 'arch=arm64') 'platform=ios' to build for ios-arm") endif endif ifeq ($(platform),ios) - ifeq ($(filter arm i386,$(arch)),) - x := $(error "please specify 'arch=i386' or 'arch=arm' with 'platform=ios'") + ifeq ($(filter i386 arm arm64,$(arch)),) + x := $(error "please specify 'arch=i386', 'arch=arm', or 'arch=arm64' with 'platform=ios'") endif endif diff --git a/src/arm.S b/src/arm.S index 5d33b2cb58..8cf09b1de3 100644 --- a/src/arm.S +++ b/src/arm.S @@ -51,7 +51,7 @@ GLOBAL(vmNativeCall): mov w23, w6 // setup stack arguments if necessary - sub sp, sp, w20 // allocate stack + sub sp, sp, w20, uxtw // allocate stack mov x9, sp LOCAL(loop): cmp w3, wzr @@ -79,16 +79,16 @@ LOCAL(populateVFPs): LOCAL(doCall): blr x19 // call function - add sp, sp, w20 // deallocate stack + add sp, sp, w20, uxtw // deallocate stack cmp w23,#FLOAT_TYPE - bne LOCAL(double) + b.ne LOCAL(double) fmov w0,s0 b LOCAL(exit) LOCAL(double): cmp w23,#DOUBLE_TYPE - bne LOCAL(exit) + b.ne LOCAL(exit) fmov x0,d0 LOCAL(exit): diff --git a/src/avian/arm.h b/src/avian/arm.h index 9fbc83c474..8696507735 100644 --- a/src/avian/arm.h +++ b/src/avian/arm.h @@ -34,7 +34,11 @@ #define THREAD_STATE_IP(state) ((state).FIELD(pc)) #define THREAD_STATE_STACK(state) ((state).FIELD(sp)) +#if (defined __APPLE__) && (defined ARCH_arm64) +#define THREAD_STATE_THREAD(state) ((state).FIELD(x[8])) +#else #define THREAD_STATE_THREAD(state) ((state).FIELD(r[8])) +#endif #define THREAD_STATE_LINK(state) ((state).FIELD(lr)) #define IP_REGISTER(context) THREAD_STATE_IP(context->uc_mcontext->FIELD(ss)) diff --git a/src/tools/object-writer/mach-o.cpp b/src/tools/object-writer/mach-o.cpp index 524407a381..c35a7058ac 100644 --- a/src/tools/object-writer/mach-o.cpp +++ b/src/tools/object-writer/mach-o.cpp @@ -33,10 +33,12 @@ #define CPU_TYPE_I386 7 #define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64) #define CPU_TYPE_ARM 12 +#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) #define CPU_SUBTYPE_I386_ALL 3 #define CPU_SUBTYPE_X86_64_ALL CPU_SUBTYPE_I386_ALL #define CPU_SUBTYPE_ARM_V7 9 +#define CPU_SUBTYPE_ARM_V8 13 namespace { @@ -157,6 +159,10 @@ class MachOPlatform : public Platform { cpuType = CPU_TYPE_ARM; cpuSubType = CPU_SUBTYPE_ARM_V7; break; + case PlatformInfo::Arm64: + cpuType = CPU_TYPE_ARM64; + cpuSubType = CPU_SUBTYPE_ARM_V8; + break; default: // should never happen (see MachOPlatform declarations at bottom) fprintf(stderr, "unsupported architecture: %d\n", info.arch); @@ -280,6 +286,7 @@ class MachOPlatform : public Platform { MachOPlatform darwinx86Platform(PlatformInfo::x86); MachOPlatform darwinArmPlatform(PlatformInfo::Arm); +MachOPlatform darwinArm64Platform(PlatformInfo::Arm64); MachOPlatform darwinx86_64Platform(PlatformInfo::x86_64); } // namespace From 46e445017ec8cccd0e99c92488c553f6e611a3d5 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 9 Dec 2014 14:53:12 -0700 Subject: [PATCH 29/70] make sure binary-to-object doesn't generate empty objects for invalid format/architecture combinations --- src/tools/binary-to-object/main.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/tools/binary-to-object/main.cpp b/src/tools/binary-to-object/main.cpp index 1636d46dfd..ed984b12f5 100644 --- a/src/tools/binary-to-object/main.cpp +++ b/src/tools/binary-to-object/main.cpp @@ -50,20 +50,11 @@ bool writeObject(uint8_t* data, OutputStream* out, const char* startName, const char* endName, - const char* format, - const char* architecture, + Platform* platform, unsigned alignment, bool writable, bool executable) { - Platform* platform = Platform::getPlatform( - PlatformInfo(PlatformInfo::formatFromString(format), - PlatformInfo::archFromString(architecture))); - - if (!platform) { - fprintf(stderr, "unsupported platform: %s/%s\n", format, architecture); - return false; - } SymbolInfo symbols[] = {SymbolInfo(0, startName), SymbolInfo(size, endName)}; @@ -113,6 +104,19 @@ int main(int argc, const char** argv) } } + const char* format = argv[5]; + const char* architecture = argv[6]; + + Platform* platform = Platform::getPlatform( + PlatformInfo(PlatformInfo::formatFromString(format), + PlatformInfo::archFromString(architecture))); + + if (!platform) { + fprintf(stderr, "unsupported platform: %s/%s\n", format, architecture); + return 1; + } + + uint8_t* data = 0; unsigned size; int fd = open(argv[1], O_RDONLY); @@ -148,8 +152,7 @@ int main(int argc, const char** argv) &out, argv[3], argv[4], - argv[5], - argv[6], + platform, alignment, writable, executable); From 8be7b6aeb30accce1bf99b958f5c815b8eb7038c Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 9 Dec 2014 16:34:46 -0700 Subject: [PATCH 30/70] correct THREAD_STATE_THREAD register for arm64 on darwin --- src/avian/arm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/avian/arm.h b/src/avian/arm.h index 8696507735..c0309486a3 100644 --- a/src/avian/arm.h +++ b/src/avian/arm.h @@ -35,7 +35,7 @@ #define THREAD_STATE_IP(state) ((state).FIELD(pc)) #define THREAD_STATE_STACK(state) ((state).FIELD(sp)) #if (defined __APPLE__) && (defined ARCH_arm64) -#define THREAD_STATE_THREAD(state) ((state).FIELD(x[8])) +#define THREAD_STATE_THREAD(state) ((state).FIELD(x[19])) #else #define THREAD_STATE_THREAD(state) ((state).FIELD(r[8])) #endif From f8b9fcf1989c043f31bcaab0407687d34aaf24b2 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 10 Dec 2014 14:41:46 -0700 Subject: [PATCH 31/70] split asm files by architecture (x86 -> i386,x86_64 ; arm -> arm,arm64) --- makefile | 4 +- src/arm.S | 130 ------ src/arm64.S | 146 +++++++ src/compile-arm64.S | 26 ++ src/{compile-x86.S => compile-i386.S} | 0 src/{compile-x86.masm => compile-i386.masm} | 0 src/compile-x86_64.S | 455 ++++++++++++++++++++ src/i386.S | 145 +++++++ src/{x86.masm => i386.masm} | 0 src/{x86.S => x86_64.S} | 129 ------ 10 files changed, 774 insertions(+), 261 deletions(-) create mode 100644 src/arm64.S create mode 100644 src/compile-arm64.S rename src/{compile-x86.S => compile-i386.S} (100%) rename src/{compile-x86.masm => compile-i386.masm} (100%) create mode 100644 src/compile-x86_64.S create mode 100644 src/i386.S rename src/{x86.masm => i386.masm} (100%) rename src/{x86.S => x86_64.S} (73%) diff --git a/makefile b/makefile index 791fa4d765..008a230901 100755 --- a/makefile +++ b/makefile @@ -1206,7 +1206,7 @@ vm-sources = \ $(src)/jnienv.cpp \ $(src)/process.cpp -vm-asm-sources = $(src)/$(asm).$(asm-format) +vm-asm-sources = $(src)/$(arch).$(asm-format) target-asm = $(asm) @@ -1257,7 +1257,7 @@ ifeq ($(process),compile) endif endif - vm-asm-sources += $(src)/compile-$(asm).$(asm-format) + vm-asm-sources += $(src)/compile-$(arch).$(asm-format) endif cflags += -DAVIAN_PROCESS_$(process) ifeq ($(aot-only),true) diff --git a/src/arm.S b/src/arm.S index 8cf09b1de3..62eea48658 100644 --- a/src/arm.S +++ b/src/arm.S @@ -21,134 +21,6 @@ # define GLOBAL(x) x #endif -#ifdef __aarch64__ - -.globl GLOBAL(vmNativeCall) -.align 2 -GLOBAL(vmNativeCall): - // arguments: - // x0 -> x19 : function - // w1 -> w20 : stackTotal - // x2 : memoryTable - // w3 : memoryCount - // x4 -> x21 : gprTable - // x5 -> x22 : vfpTable - // w6 -> w23 : returnType - - // allocate frame - stp x29, x30, [sp,#-64]! - - // save callee-saved register values so we can clobber them - stp x19, x20, [sp,#16] - stp x21, x22, [sp,#32] - str x23, [sp,#48] - - // move arguments into callee-saved registers - mov x19, x0 - mov w20, w1 - mov x21, x4 - mov x22, x5 - mov w23, w6 - - // setup stack arguments if necessary - sub sp, sp, w20, uxtw // allocate stack - mov x9, sp -LOCAL(loop): - cmp w3, wzr - b.eq LOCAL(populateGPRs) - ldr x0, [x2], #8 - str x0, [x9], #8 - sub w3, w3, #8 - b LOCAL(loop) - -LOCAL(populateGPRs): - cmp x21, xzr - b.eq LOCAL(populateVFPs) - ldp x0, x1, [x21] - ldp x2, x3, [x21,#16] - ldp x4, x5, [x21,#32] - ldp x6, x7, [x21,#48] - -LOCAL(populateVFPs): - cmp x22, xzr - b.eq LOCAL(doCall) - ldp d0, d1, [x22] - ldp d2, d3, [x22,#16] - ldp d4, d5, [x22,#32] - ldp d6, d7, [x22,#48] - -LOCAL(doCall): - blr x19 // call function - add sp, sp, w20, uxtw // deallocate stack - - cmp w23,#FLOAT_TYPE - b.ne LOCAL(double) - fmov w0,s0 - b LOCAL(exit) - -LOCAL(double): - cmp w23,#DOUBLE_TYPE - b.ne LOCAL(exit) - fmov x0,d0 - -LOCAL(exit): - ldp x19, x20, [sp,#16] - ldp x21, x22, [sp,#32] - ldr x23, [sp,#48] - ldp x29, x30, [sp],#64 - ret - -.globl GLOBAL(vmJump) -.align 2 -GLOBAL(vmJump): - mov x30, x0 - mov x0, x4 - mov x1, x5 - mov sp, x2 - mov x19, x3 - br x30 - -#define CHECKPOINT_THREAD 8 -#define CHECKPOINT_STACK 48 - -.globl GLOBAL(vmRun) -.align 2 -GLOBAL(vmRun): - // x0: function - // x1: arguments - // x2: checkpoint - - // allocate frame - stp x29, x30, [sp,#-96]! - - // save callee-saved register values - stp x19, x20, [sp,#16] - stp x21, x22, [sp,#32] - stp x23, x24, [sp,#48] - stp x25, x26, [sp,#64] - stp x27, x28, [sp,#80] - - mov x19, sp - str x19, [x2, #CHECKPOINT_STACK] - - mov x19, x0 - ldr x0, [x2, #CHECKPOINT_THREAD] - - blr x19 - -.globl GLOBAL(vmRun_returnAddress) -.align 2 -GLOBAL(vmRun_returnAddress): - ldp x19, x20, [sp,#16] - ldp x21, x22, [sp,#32] - ldp x23, x24, [sp,#48] - ldp x25, x26, [sp,#64] - ldp x27, x28, [sp,#80] - ldp x29, x30, [sp],#96 - br x30 - -#elif defined __arm__ - .globl GLOBAL(vmNativeCall) .align 2 GLOBAL(vmNativeCall): @@ -258,5 +130,3 @@ GLOBAL(vmRun_returnAddress): add sp, sp, #12 ldmfd sp!, {r4-r11, lr} bx lr - -#endif // __arm__ diff --git a/src/arm64.S b/src/arm64.S new file mode 100644 index 0000000000..6953ea0cf6 --- /dev/null +++ b/src/arm64.S @@ -0,0 +1,146 @@ +/* arm.S: JNI gluecode for ARM + Copyright (c) 2008-2014, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include "avian/types.h" + +.text + +#define LOCAL(x) .L##x + +#ifdef __APPLE__ +# define GLOBAL(x) _##x +#else +# define GLOBAL(x) x +#endif + +.globl GLOBAL(vmNativeCall) +.align 2 +GLOBAL(vmNativeCall): + // arguments: + // x0 -> x19 : function + // w1 -> w20 : stackTotal + // x2 : memoryTable + // w3 : memoryCount + // x4 -> x21 : gprTable + // x5 -> x22 : vfpTable + // w6 -> w23 : returnType + + // allocate frame + stp x29, x30, [sp,#-64]! + + // save callee-saved register values so we can clobber them + stp x19, x20, [sp,#16] + stp x21, x22, [sp,#32] + str x23, [sp,#48] + + // move arguments into callee-saved registers + mov x19, x0 + mov w20, w1 + mov x21, x4 + mov x22, x5 + mov w23, w6 + + // setup stack arguments if necessary + sub sp, sp, w20, uxtw // allocate stack + mov x9, sp +LOCAL(loop): + cmp w3, wzr + b.eq LOCAL(populateGPRs) + ldr x0, [x2], #8 + str x0, [x9], #8 + sub w3, w3, #8 + b LOCAL(loop) + +LOCAL(populateGPRs): + cmp x21, xzr + b.eq LOCAL(populateVFPs) + ldp x0, x1, [x21] + ldp x2, x3, [x21,#16] + ldp x4, x5, [x21,#32] + ldp x6, x7, [x21,#48] + +LOCAL(populateVFPs): + cmp x22, xzr + b.eq LOCAL(doCall) + ldp d0, d1, [x22] + ldp d2, d3, [x22,#16] + ldp d4, d5, [x22,#32] + ldp d6, d7, [x22,#48] + +LOCAL(doCall): + blr x19 // call function + add sp, sp, w20, uxtw // deallocate stack + + cmp w23,#FLOAT_TYPE + b.ne LOCAL(double) + fmov w0,s0 + b LOCAL(exit) + +LOCAL(double): + cmp w23,#DOUBLE_TYPE + b.ne LOCAL(exit) + fmov x0,d0 + +LOCAL(exit): + ldp x19, x20, [sp,#16] + ldp x21, x22, [sp,#32] + ldr x23, [sp,#48] + ldp x29, x30, [sp],#64 + ret + +.globl GLOBAL(vmJump) +.align 2 +GLOBAL(vmJump): + mov x30, x0 + mov x0, x4 + mov x1, x5 + mov sp, x2 + mov x19, x3 + br x30 + +#define CHECKPOINT_THREAD 8 +#define CHECKPOINT_STACK 48 + +.globl GLOBAL(vmRun) +.align 2 +GLOBAL(vmRun): + // x0: function + // x1: arguments + // x2: checkpoint + + // allocate frame + stp x29, x30, [sp,#-96]! + + // save callee-saved register values + stp x19, x20, [sp,#16] + stp x21, x22, [sp,#32] + stp x23, x24, [sp,#48] + stp x25, x26, [sp,#64] + stp x27, x28, [sp,#80] + + mov x19, sp + str x19, [x2, #CHECKPOINT_STACK] + + mov x19, x0 + ldr x0, [x2, #CHECKPOINT_THREAD] + + blr x19 + +.globl GLOBAL(vmRun_returnAddress) +.align 2 +GLOBAL(vmRun_returnAddress): + ldp x19, x20, [sp,#16] + ldp x21, x22, [sp,#32] + ldp x23, x24, [sp,#48] + ldp x25, x26, [sp,#64] + ldp x27, x28, [sp,#80] + ldp x29, x30, [sp],#96 + br x30 diff --git a/src/compile-arm64.S b/src/compile-arm64.S new file mode 100644 index 0000000000..5b4ef5098a --- /dev/null +++ b/src/compile-arm64.S @@ -0,0 +1,26 @@ +/* Copyright (c) 2008-2014, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include "avian/types.h" +#include "avian/target-fields.h" + +.text + +#define BYTES_PER_WORD 4 + +#define LOCAL(x) .L##x + +#ifdef __APPLE__ +# define GLOBAL(x) _##x +#else +# define GLOBAL(x) x +#endif + +#error not implemented \ No newline at end of file diff --git a/src/compile-x86.S b/src/compile-i386.S similarity index 100% rename from src/compile-x86.S rename to src/compile-i386.S diff --git a/src/compile-x86.masm b/src/compile-i386.masm similarity index 100% rename from src/compile-x86.masm rename to src/compile-i386.masm diff --git a/src/compile-x86_64.S b/src/compile-x86_64.S new file mode 100644 index 0000000000..1938bd5aae --- /dev/null +++ b/src/compile-x86_64.S @@ -0,0 +1,455 @@ +/* Copyright (c) 2008-2014, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include "avian/types.h" +#include "avian/target-fields.h" + +#define LOCAL(x) .L##x + +#if defined __APPLE__ \ + || ((defined __MINGW32__ || defined __CYGWIN32__) && ! defined __x86_64__) +# define GLOBAL(x) _##x +#else +# define GLOBAL(x) x +#endif + +.text + +#ifdef __x86_64__ + +#ifdef AVIAN_USE_FRAME_POINTER +# define ALIGNMENT_ADJUSTMENT 0 +#else +# define ALIGNMENT_ADJUSTMENT 8 +#endif + +#if defined __MINGW32__ || defined __CYGWIN32__ + +#define CALLEE_SAVED_REGISTER_FOOTPRINT 64 + ALIGNMENT_ADJUSTMENT + +.globl GLOBAL(vmInvoke) +GLOBAL(vmInvoke): + pushq %rbp + movq %rsp,%rbp + + // %rcx: thread + // %rdx: function + // %r8 : arguments + // %r9 : argumentsFootprint + // 48(%rbp) : frameSize + // 56(%rbp) : returnType (ignored) + + // allocate stack space for callee-saved registers + subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp + + // remember this stack position, since we won't be able to rely on + // %rbp being restored when the call returns + movq %rsp,TARGET_THREAD_SCRATCH(%rcx) + + // save callee-saved registers + movq %rbx,0(%rsp) + movq %r12,8(%rsp) + movq %r13,16(%rsp) + movq %r14,24(%rsp) + movq %r15,32(%rsp) + movq %rsi,40(%rsp) + movq %rdi,48(%rsp) + + // allocate stack space for arguments + movl 48(%rbp),%eax + subq %rax,%rsp + + // we use rbx to hold the thread pointer, by convention + mov %rcx,%rbx + + // copy arguments into place + movq $0,%r11 + jmp LOCAL(vmInvoke_argumentTest) + +LOCAL(vmInvoke_argumentLoop): + movq (%r8,%r11,1),%rsi + movq %rsi,(%rsp,%r11,1) + addq $8,%r11 + +LOCAL(vmInvoke_argumentTest): + cmpq %r9,%r11 + jb LOCAL(vmInvoke_argumentLoop) + + // call function + call *%rdx + +.globl GLOBAL(vmInvoke_returnAddress) +GLOBAL(vmInvoke_returnAddress): + // restore stack pointer + movq TARGET_THREAD_SCRATCH(%rbx),%rsp + + // clear MyThread::stack to avoid confusing another thread calling + // java.lang.Thread.getStackTrace on this one. See + // MyProcess::getStackTrace in compile.cpp for details on how we get + // a reliable stack trace from a thread that might be interrupted at + // any point in its execution. + movq $0,TARGET_THREAD_STACK(%rbx) + +.globl GLOBAL(vmInvoke_safeStack) +GLOBAL(vmInvoke_safeStack): + +#ifdef AVIAN_CONTINUATIONS +# include "continuations-x86.S" +#endif // AVIAN_CONTINUATIONS + + // restore callee-saved registers + movq 0(%rsp),%rbx + movq 8(%rsp),%r12 + movq 16(%rsp),%r13 + movq 24(%rsp),%r14 + movq 32(%rsp),%r15 + movq 40(%rsp),%rsi + movq 48(%rsp),%rdi + + addq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp + + // return + popq %rbp + ret + +.globl GLOBAL(vmJumpAndInvoke) +GLOBAL(vmJumpAndInvoke): +#ifdef AVIAN_CONTINUATIONS + // %rcx: thread + // %rdx: address + // %r8 : stack + // %r9 : argumentFootprint + // 40(%rsp): arguments + // 48(%rsp): frameSize + + // allocate new frame, adding room for callee-saved registers + movl 48(%rsp),%eax + subq %rax,%r8 + subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%r8 + + movq %rcx,%rbx + + // set return address + leaq GLOBAL(vmInvoke_returnAddress)(%rip),%r10 + movq %r10,(%r8) + + // copy arguments into place + movq $0,%r11 + movl 40(%rsp),%eax + jmp LOCAL(vmJumpAndInvoke_argumentTest) + +LOCAL(vmJumpAndInvoke_argumentLoop): + movq (%rax,%r11,1),%r10 + movq %r10,8(%r8,%r11,1) + addq $8,%r11 + +LOCAL(vmJumpAndInvoke_argumentTest): + cmpq %r9,%r11 + jb LOCAL(vmJumpAndInvoke_argumentLoop) + + // the arguments have been copied, so we can set the real stack + // pointer now + movq %r8,%rsp + + jmp *%rdx +#else // not AVIAN_CONTINUATIONS + // vmJumpAndInvoke should only be called when continuations are + // enabled + int3 +#endif // not AVIAN_CONTINUATIONS + +#else // not __MINGW32__ || __CYGWIN32__ + +#define CALLEE_SAVED_REGISTER_FOOTPRINT 48 + ALIGNMENT_ADJUSTMENT + +.globl GLOBAL(vmInvoke) +GLOBAL(vmInvoke): + pushq %rbp + movq %rsp,%rbp + + // %rdi: thread + // %rsi: function + // %rdx: arguments + // %rcx: argumentFootprint + // %r8 : frameSize + // %r9 : returnType (ignored) + + // allocate stack space for callee-saved registers + subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp + + // remember this stack position, since we won't be able to rely on + // %rbp being restored when the call returns + movq %rsp,TARGET_THREAD_SCRATCH(%rdi) + + // save callee-saved registers + movq %rbx,0(%rsp) + movq %r12,8(%rsp) + movq %r13,16(%rsp) + movq %r14,24(%rsp) + movq %r15,32(%rsp) + + // allocate stack space for arguments + subq %r8,%rsp + + // we use rbx to hold the thread pointer, by convention + mov %rdi,%rbx + + // copy arguments into place + movq $0,%r9 + jmp LOCAL(vmInvoke_argumentTest) + +LOCAL(vmInvoke_argumentLoop): + movq (%rdx,%r9,1),%r8 + movq %r8,(%rsp,%r9,1) + addq $8,%r9 + +LOCAL(vmInvoke_argumentTest): + cmpq %rcx,%r9 + jb LOCAL(vmInvoke_argumentLoop) + + // call function + call *%rsi + +.globl GLOBAL(vmInvoke_returnAddress) +GLOBAL(vmInvoke_returnAddress): + // restore stack pointer + movq TARGET_THREAD_SCRATCH(%rbx),%rsp + + // clear MyThread::stack to avoid confusing another thread calling + // java.lang.Thread.getStackTrace on this one. See + // MyProcess::getStackTrace in compile.cpp for details on how we get + // a reliable stack trace from a thread that might be interrupted at + // any point in its execution. + movq $0,TARGET_THREAD_STACK(%rbx) + +.globl GLOBAL(vmInvoke_safeStack) +GLOBAL(vmInvoke_safeStack): + +#ifdef AVIAN_CONTINUATIONS +# include "continuations-x86.S" +#endif // AVIAN_CONTINUATIONS + + // restore callee-saved registers + movq 0(%rsp),%rbx + movq 8(%rsp),%r12 + movq 16(%rsp),%r13 + movq 24(%rsp),%r14 + movq 32(%rsp),%r15 + + addq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp + + // return + popq %rbp + ret + +.globl GLOBAL(vmJumpAndInvoke) +GLOBAL(vmJumpAndInvoke): +#ifdef AVIAN_CONTINUATIONS + // %rdi: thread + // %rsi: address + // %rdx: stack + // %rcx: argumentFootprint + // %r8 : arguments + // %r9 : frameSize + + // allocate new frame, adding room for callee-saved registers + subq %r9,%rdx + subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rdx + + movq %rdi,%rbx + + // set return address + movq GLOBAL(vmInvoke_returnAddress)@GOTPCREL(%rip),%r10 + movq %r10,(%rdx) + + // copy arguments into place + movq $0,%r11 + jmp LOCAL(vmJumpAndInvoke_argumentTest) + +LOCAL(vmJumpAndInvoke_argumentLoop): + movq (%r8,%r11,1),%r10 + movq %r10,8(%rdx,%r11,1) + addq $8,%r11 + +LOCAL(vmJumpAndInvoke_argumentTest): + cmpq %rcx,%r11 + jb LOCAL(vmJumpAndInvoke_argumentLoop) + + // the arguments have been copied, so we can set the real stack + // pointer now + movq %rdx,%rsp + + jmp *%rsi +#else // not AVIAN_CONTINUATIONS + // vmJumpAndInvoke should only be called when continuations are + // enabled + int3 +#endif // not AVIAN_CONTINUATIONS + +#endif // not __MINGW32__ || __CYGWIN32__ + +#elif defined __i386__ + +#ifdef AVIAN_USE_FRAME_POINTER +# define ALIGNMENT_ADJUSTMENT 0 +#else +# define ALIGNMENT_ADJUSTMENT 12 +#endif + +#define CALLEE_SAVED_REGISTER_FOOTPRINT 16 + ALIGNMENT_ADJUSTMENT + +.globl GLOBAL(vmInvoke) +GLOBAL(vmInvoke): + pushl %ebp + movl %esp,%ebp + + // 8(%ebp): thread + // 12(%ebp): function + // 16(%ebp): arguments + // 20(%ebp): argumentFootprint + // 24(%ebp): frameSize + // 28(%ebp): returnType + + // allocate stack space for callee-saved registers + subl $CALLEE_SAVED_REGISTER_FOOTPRINT,%esp + + // remember this stack position, since we won't be able to rely on + // %rbp being restored when the call returns + movl 8(%ebp),%eax + movl %esp,TARGET_THREAD_SCRATCH(%eax) + + movl %ebx,0(%esp) + movl %esi,4(%esp) + movl %edi,8(%esp) + + // allocate stack space for arguments + subl 24(%ebp),%esp + + // we use ebx to hold the thread pointer, by convention + mov %eax,%ebx + + // copy arguments into place + movl $0,%ecx + movl 16(%ebp),%edx + jmp LOCAL(vmInvoke_argumentTest) + +LOCAL(vmInvoke_argumentLoop): + movl (%edx,%ecx,1),%eax + movl %eax,(%esp,%ecx,1) + addl $4,%ecx + +LOCAL(vmInvoke_argumentTest): + cmpl 20(%ebp),%ecx + jb LOCAL(vmInvoke_argumentLoop) + + // call function + call *12(%ebp) + +.globl GLOBAL(vmInvoke_returnAddress) +GLOBAL(vmInvoke_returnAddress): + // restore stack pointer + movl TARGET_THREAD_SCRATCH(%ebx),%esp + + // clear MyThread::stack to avoid confusing another thread calling + // java.lang.Thread.getStackTrace on this one. See + // MyProcess::getStackTrace in compile.cpp for details on how we get + // a reliable stack trace from a thread that might be interrupted at + // any point in its execution. + movl $0,TARGET_THREAD_STACK(%ebx) + +.globl GLOBAL(vmInvoke_safeStack) +GLOBAL(vmInvoke_safeStack): + +#ifdef AVIAN_CONTINUATIONS +# include "continuations-x86.S" +#endif // AVIAN_CONTINUATIONS + + // restore callee-saved registers + movl 0(%esp),%ebx + movl 4(%esp),%esi + movl 8(%esp),%edi + + addl $CALLEE_SAVED_REGISTER_FOOTPRINT,%esp + + // handle return value based on expected type + movl 28(%esp),%ecx + + popl %ebp + ret + +LOCAL(getPC): + movl (%esp),%esi + ret + +.globl GLOBAL(vmJumpAndInvoke) +GLOBAL(vmJumpAndInvoke): +#ifdef AVIAN_CONTINUATIONS + // 4(%esp): thread + // 8(%esp): address + // 12(%esp): stack + // 16(%esp): argumentFootprint + // 20(%esp): arguments + // 24(%esp): frameSize + + movl 12(%esp),%ecx + + // allocate new frame, adding room for callee-saved registers, + // return address, and frame pointer + subl 24(%esp),%ecx + subl $CALLEE_SAVED_REGISTER_FOOTPRINT+8,%ecx + + movl 4(%esp),%ebx + + // set return address +#if defined __MINGW32__ || defined __CYGWIN32__ + movl $GLOBAL(vmInvoke_returnAddress),%esi +#else + call LOCAL(getPC) +# if defined __APPLE__ +LOCAL(vmJumpAndInvoke_offset): + leal GLOBAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_offset)(%esi),%esi +# else + addl $_GLOBAL_OFFSET_TABLE_,%esi + movl GLOBAL(vmInvoke_returnAddress)@GOT(%esi),%esi +# endif +#endif + movl %esi,(%ecx) + + // copy arguments into place + movl $0,%esi + movl 16(%esp),%edx + movl 20(%esp),%eax + jmp LOCAL(vmJumpAndInvoke_argumentTest) + +LOCAL(vmJumpAndInvoke_argumentLoop): + movl (%eax,%esi,1),%edi + movl %edi,4(%ecx,%esi,1) + addl $4,%esi + +LOCAL(vmJumpAndInvoke_argumentTest): + cmpl %edx,%esi + jb LOCAL(vmJumpAndInvoke_argumentLoop) + + movl 8(%esp),%esi + + // the arguments have been copied, so we can set the real stack + // pointer now + movl %ecx,%esp + + jmp *%esi +#else // not AVIAN_CONTINUATIONS + // vmJumpAndInvoke should only be called when continuations are + // enabled + int3 +#endif // AVIAN_CONTINUATIONS + +#else +#error unsupported architecture +#endif //def __x86_64__ diff --git a/src/i386.S b/src/i386.S new file mode 100644 index 0000000000..c8ee92c46b --- /dev/null +++ b/src/i386.S @@ -0,0 +1,145 @@ +/* Copyright (c) 2008-2014, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include "avian/types.h" + +#define LOCAL(x) .L##x + +#if defined __APPLE__ \ + || ((defined __MINGW32__ || defined __CYGWIN32__) && ! defined __x86_64__) +# define GLOBAL(x) _##x +#else +# define GLOBAL(x) x +#endif + +.text + +#define CHECKPOINT_THREAD 4 +#define CHECKPOINT_STACK 24 +#define CHECKPOINT_BASE 28 + +.globl GLOBAL(vmNativeCall) +GLOBAL(vmNativeCall): + pushl %ebp + movl %esp,%ebp + + // 8(%ebp): function + // 12(%ebp): stack + // 16(%ebp): stackSize + // 20(%ebp): returnType + + // reserve space for arguments + movl 16(%ebp),%ecx + + subl %ecx,%esp + +//# ifdef __APPLE__ + // align to a 16 byte boundary + andl $0xFFFFFFF0,%esp +//# endif + + // copy arguments into place + movl $0,%ecx + jmp LOCAL(test) + +LOCAL(loop): + movl %ecx,%eax + movl %ecx,%edx + addl %esp,%edx + addl 12(%ebp),%eax + movl (%eax),%eax + movl %eax,(%edx) + addl $4,%ecx + +LOCAL(test): + cmpl 16(%ebp),%ecx + jb LOCAL(loop) + + // call function + call *8(%ebp) + + // handle return value based on expected type + movl 20(%ebp),%ecx + +LOCAL(void): + cmpl $VOID_TYPE,%ecx + jne LOCAL(int64) + jmp LOCAL(exit) + +LOCAL(int64): + cmpl $INT64_TYPE,%ecx + jne LOCAL(float) + jmp LOCAL(exit) + +LOCAL(float): + cmpl $FLOAT_TYPE,%ecx + jne LOCAL(double) + fstps 8(%ebp) + movl 8(%ebp),%eax + jmp LOCAL(exit) + +LOCAL(double): + cmpl $DOUBLE_TYPE,%ecx + jne LOCAL(exit) + fstpl 8(%ebp) + movl 8(%ebp),%eax + movl 12(%ebp),%edx + +LOCAL(exit): + movl %ebp,%esp + popl %ebp + ret + +.globl GLOBAL(vmJump) +GLOBAL(vmJump): + movl 4(%esp),%esi + movl 8(%esp),%ebp + movl 16(%esp),%ebx + movl 20(%esp),%eax + movl 24(%esp),%edx + movl 12(%esp),%esp + jmp *%esi + +#define VMRUN_FRAME_SIZE 24 + +.globl GLOBAL(vmRun) +GLOBAL(vmRun): + // 8(%ebp): function + // 12(%ebp): arguments + // 16(%ebp): checkpoint + pushl %ebp + movl %esp,%ebp + subl $VMRUN_FRAME_SIZE,%esp + + movl %ebx,8(%esp) + movl %esi,12(%esp) + movl %edi,16(%esp) + + movl 12(%ebp),%eax + movl %eax,4(%esp) + + movl 16(%ebp),%ecx + movl CHECKPOINT_THREAD(%ecx),%eax + movl %eax,0(%esp) + + movl %esp,CHECKPOINT_STACK(%ecx) + + call *8(%ebp) + +.globl GLOBAL(vmRun_returnAddress) +GLOBAL(vmRun_returnAddress): + + movl 8(%esp),%ebx + movl 12(%esp),%esi + movl 16(%esp),%edi + + addl $VMRUN_FRAME_SIZE,%esp + popl %ebp + ret diff --git a/src/x86.masm b/src/i386.masm similarity index 100% rename from src/x86.masm rename to src/i386.masm diff --git a/src/x86.S b/src/x86_64.S similarity index 73% rename from src/x86.S rename to src/x86_64.S index c02882d31d..32db292af4 100644 --- a/src/x86.S +++ b/src/x86_64.S @@ -21,8 +21,6 @@ .text -#ifdef __x86_64__ - #define CHECKPOINT_THREAD 8 #define CHECKPOINT_STACK 48 @@ -340,130 +338,3 @@ GLOBAL(vmRun_returnAddress): ret #endif // not __MINGW32__ - -#elif defined __i386__ - -#define CHECKPOINT_THREAD 4 -#define CHECKPOINT_STACK 24 -#define CHECKPOINT_BASE 28 - -.globl GLOBAL(vmNativeCall) -GLOBAL(vmNativeCall): - pushl %ebp - movl %esp,%ebp - - // 8(%ebp): function - // 12(%ebp): stack - // 16(%ebp): stackSize - // 20(%ebp): returnType - - // reserve space for arguments - movl 16(%ebp),%ecx - - subl %ecx,%esp - -//# ifdef __APPLE__ - // align to a 16 byte boundary - andl $0xFFFFFFF0,%esp -//# endif - - // copy arguments into place - movl $0,%ecx - jmp LOCAL(test) - -LOCAL(loop): - movl %ecx,%eax - movl %ecx,%edx - addl %esp,%edx - addl 12(%ebp),%eax - movl (%eax),%eax - movl %eax,(%edx) - addl $4,%ecx - -LOCAL(test): - cmpl 16(%ebp),%ecx - jb LOCAL(loop) - - // call function - call *8(%ebp) - - // handle return value based on expected type - movl 20(%ebp),%ecx - -LOCAL(void): - cmpl $VOID_TYPE,%ecx - jne LOCAL(int64) - jmp LOCAL(exit) - -LOCAL(int64): - cmpl $INT64_TYPE,%ecx - jne LOCAL(float) - jmp LOCAL(exit) - -LOCAL(float): - cmpl $FLOAT_TYPE,%ecx - jne LOCAL(double) - fstps 8(%ebp) - movl 8(%ebp),%eax - jmp LOCAL(exit) - -LOCAL(double): - cmpl $DOUBLE_TYPE,%ecx - jne LOCAL(exit) - fstpl 8(%ebp) - movl 8(%ebp),%eax - movl 12(%ebp),%edx - -LOCAL(exit): - movl %ebp,%esp - popl %ebp - ret - -.globl GLOBAL(vmJump) -GLOBAL(vmJump): - movl 4(%esp),%esi - movl 8(%esp),%ebp - movl 16(%esp),%ebx - movl 20(%esp),%eax - movl 24(%esp),%edx - movl 12(%esp),%esp - jmp *%esi - -#define VMRUN_FRAME_SIZE 24 - -.globl GLOBAL(vmRun) -GLOBAL(vmRun): - // 8(%ebp): function - // 12(%ebp): arguments - // 16(%ebp): checkpoint - pushl %ebp - movl %esp,%ebp - subl $VMRUN_FRAME_SIZE,%esp - - movl %ebx,8(%esp) - movl %esi,12(%esp) - movl %edi,16(%esp) - - movl 12(%ebp),%eax - movl %eax,4(%esp) - - movl 16(%ebp),%ecx - movl CHECKPOINT_THREAD(%ecx),%eax - movl %eax,0(%esp) - - movl %esp,CHECKPOINT_STACK(%ecx) - - call *8(%ebp) - -.globl GLOBAL(vmRun_returnAddress) -GLOBAL(vmRun_returnAddress): - - movl 8(%esp),%ebx - movl 12(%esp),%esi - movl 16(%esp),%edi - - addl $VMRUN_FRAME_SIZE,%esp - popl %ebp - ret - -#endif // __i386__ From a200d4d529ecaccb734b06119be4ae4d0c5bb93c Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 10 Dec 2014 15:11:55 -0700 Subject: [PATCH 32/70] pull in initial version of compile-arm64.S, to fix arm64 build (untested) Initial implementation courtesy Joel Dice (@dicej) --- src/compile-arm64.S | 105 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/src/compile-arm64.S b/src/compile-arm64.S index 5b4ef5098a..43023556bf 100644 --- a/src/compile-arm64.S +++ b/src/compile-arm64.S @@ -23,4 +23,107 @@ # define GLOBAL(x) x #endif -#error not implemented \ No newline at end of file +#define CONTINUATION_NEXT 4 +#define CONTINUATION_ADDRESS 16 +#define CONTINUATION_RETURN_ADDRESS_OFFSET 20 +#define CONTINUATION_FRAME_POINTER_OFFSET 24 +#define CONTINUATION_LENGTH 28 +#define CONTINUATION_BODY 32 + +.globl GLOBAL(vmInvoke) +.align 2 +GLOBAL(vmInvoke): + // arguments: + // x0 : thread + // x1 : function + // x2 : arguments + // w3 : argumentFootprint + // w4 : frameSize (not used) + // w5 : returnType + + // allocate frame + stp x29, x30, [sp,#-96]! + + // save callee-saved register values + stp x19, x20, [sp,#16] + stp x21, x22, [sp,#32] + stp x23, x24, [sp,#48] + stp x25, x26, [sp,#64] + stp x27, x28, [sp,#80] + + // save return type + str w5, [sp,#-16]! + + mov x5, sp + str x5, [x0,#TARGET_THREAD_SCRATCH] + + // copy arguments into place + sub sp, sp, w3 + mov x5, #0 + b LOCAL(vmInvoke_argumentTest) + +LOCAL(vmInvoke_argumentLoop): + ldr x5, [x2, x4] + str x5, [sp, x4] + add x4, x4, #BYTES_PER_WORD + +LOCAL(vmInvoke_argumentTest): + cmp x4, x3 + blt LOCAL(vmInvoke_argumentLoop) + + // we use x19 to hold the thread pointer, by convention + mov x19, x0 + + // load and call function address + blr x1 + +.globl GLOBAL(vmInvoke_returnAddress) +.align 2 +GLOBAL(vmInvoke_returnAddress): + // restore stack pointer + ldr x5, [x19, #TARGET_THREAD_SCRATCH] + mov sp, x5 + + // clear MyThread::stack to avoid confusing another thread calling + // java.lang.Thread.getStackTrace on this one. See + // MyProcess::getStackTrace in compile.cpp for details on how we get + // a reliable stack trace from a thread that might be interrupted at + // any point in its execution. + mov x5, #0 + str x5, [x19, #TARGET_THREAD_STACK] + +.globl GLOBAL(vmInvoke_safeStack) +.align 2 +GLOBAL(vmInvoke_safeStack): + +#ifdef AVIAN_CONTINUATIONS +#error todo +#endif // AVIAN_CONTINUATIONS + + mov x5, #0 + str x5, [x19, #TARGET_THREAD_STACK] + + // restore return type + ldr w5, [sp], #4 + + // restore callee-saved register values + ldp x19, x20, [sp,#16] + ldp x21, x22, [sp,#32] + ldp x23, x24, [sp,#48] + ldp x25, x26, [sp,#64] + ldp x27, x28, [sp,#80] + ldp x29, x30, [sp],#96 + +LOCAL(vmInvoke_return): + br x30 + +.globl GLOBAL(vmJumpAndInvoke) +.align 2 +GLOBAL(vmJumpAndInvoke): +#ifdef AVIAN_CONTINUATIONS +#error todo +#else // not AVIAN_CONTINUATIONS + // vmJumpAndInvoke should only be called when continuations are + // enabled, so we force a crash if we reach here: + brk 0 +#endif // not AVIAN_CONTINUATIONS From 5ce8c2ed54926cb9e221a0df6d7a291ee5cf124d Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 10 Dec 2014 15:19:05 -0700 Subject: [PATCH 33/70] fix compile-arm64.S when using the apple toolchain --- src/compile-arm64.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compile-arm64.S b/src/compile-arm64.S index 43023556bf..65f76df6f3 100644 --- a/src/compile-arm64.S +++ b/src/compile-arm64.S @@ -58,7 +58,7 @@ GLOBAL(vmInvoke): str x5, [x0,#TARGET_THREAD_SCRATCH] // copy arguments into place - sub sp, sp, w3 + sub sp, sp, w3, uxtw mov x5, #0 b LOCAL(vmInvoke_argumentTest) @@ -69,7 +69,7 @@ LOCAL(vmInvoke_argumentLoop): LOCAL(vmInvoke_argumentTest): cmp x4, x3 - blt LOCAL(vmInvoke_argumentLoop) + b.lt LOCAL(vmInvoke_argumentLoop) // we use x19 to hold the thread pointer, by convention mov x19, x0 From 7baa5243b0a48a78cd52273cd32a22ec9dd33305 Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Fri, 12 Dec 2014 11:35:39 -0700 Subject: [PATCH 34/70] Add Collections.synchronizedList to classpath --- classpath/java/security/AccessController.java | 2 +- classpath/java/util/Collections.java | 96 ++++++++++++++++++- 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/classpath/java/security/AccessController.java b/classpath/java/security/AccessController.java index 680f0ec125..a9818d97ae 100644 --- a/classpath/java/security/AccessController.java +++ b/classpath/java/security/AccessController.java @@ -18,7 +18,7 @@ package java.security; */ public class AccessController { - public static Object doPrivileged (PrivilegedAction action) { + public static T doPrivileged (PrivilegedAction action) { return action.run(); } diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java index a098ea8b2e..e674982e16 100644 --- a/classpath/java/util/Collections.java +++ b/classpath/java/util/Collections.java @@ -340,7 +340,101 @@ public class Collections { } public static Set synchronizedSet(Set set) { - return new SynchronizedSet (new Object(), set); + return new SynchronizedSet (set, set); + } + + static class SynchronizedList + extends SynchronizedCollection + implements List + { + private final List list; + + public SynchronizedList(List list) { + super(list, list); + + this.list = list; + } + + @Override + public T get(int index) { + synchronized (lock) { + return list.get(index); + } + } + + @Override + public T set(int index, T value) { + synchronized (lock) { + return list.set(index, value); + } + } + + @Override + public T remove(int index) { + synchronized (lock) { + return list.remove(index); + } + } + + @Override + public void add(int index, T element) { + synchronized (lock) { + list.add(index, element); + } + } + + @Override + public boolean addAll(int startIndex, Collection c) { + synchronized (lock) { + return list.addAll(startIndex, c); + } + } + + @Override + public int indexOf(Object value) { + synchronized (lock) { + return list.indexOf(value); + } + } + + @Override + public int lastIndexOf(Object value) { + synchronized (lock) { + return list.lastIndexOf(value); + } + } + + @Override + public ListIterator listIterator(int index) { + // as described in the javadocs, user should be synchronized on list before calling + return list.listIterator(index); + } + + @Override + public ListIterator listIterator() { + // as described in the javadocs, user should be synchronized on list before calling + return list.listIterator(); + } + } + + static class RandomAccessSynchronizedList + extends SynchronizedList + implements RandomAccess + { + public RandomAccessSynchronizedList(List list) { + super(list); + } + } + + public static List synchronizedList(List list) { + List result; + if (list instanceof RandomAccess) { + result = new RandomAccessSynchronizedList(list); + } else { + result = new SynchronizedList(list); + } + + return result; } static class SynchronizedIterator implements Iterator { From 32a1fb21f27f76ec60d5e880de098bada8cb9661 Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Mon, 15 Dec 2014 16:26:41 -0700 Subject: [PATCH 35/70] Some small classpath tweaks to be compatible with openJDK's api --- classpath/java/util/Collections.java | 6 ++++- .../util/concurrent/ConcurrentHashMap.java | 8 +++++++ classpath/java/util/concurrent/Delayed.java | 2 +- .../java/util/concurrent/ExecutorService.java | 2 ++ classpath/java/util/concurrent/Executors.java | 24 +++++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 classpath/java/util/concurrent/Executors.java diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java index e674982e16..5267804e6c 100644 --- a/classpath/java/util/Collections.java +++ b/classpath/java/util/Collections.java @@ -38,7 +38,11 @@ public class Collections { public static void sort(List list) { sort(list, new Comparator() { public int compare(Object a, Object b) { - return ((Comparable) a).compareTo(b); + if (a instanceof Comparable) { + return ((Comparable) a).compareTo(b); + } else { + return a.hashCode() - b.hashCode(); + } } }); } diff --git a/classpath/java/util/concurrent/ConcurrentHashMap.java b/classpath/java/util/concurrent/ConcurrentHashMap.java index 9eb673bc8d..c2f8a169b6 100644 --- a/classpath/java/util/concurrent/ConcurrentHashMap.java +++ b/classpath/java/util/concurrent/ConcurrentHashMap.java @@ -49,6 +49,14 @@ public class ConcurrentHashMap this(); } + public ConcurrentHashMap(int initialCapacity, float loadFactor) { + this(); + } + + public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { + this(); + } + public boolean isEmpty() { return content.size == 0; } diff --git a/classpath/java/util/concurrent/Delayed.java b/classpath/java/util/concurrent/Delayed.java index 16d8a49d54..10b1fc834c 100644 --- a/classpath/java/util/concurrent/Delayed.java +++ b/classpath/java/util/concurrent/Delayed.java @@ -10,6 +10,6 @@ package java.util.concurrent; -public interface Delayed { +public interface Delayed extends Comparable { public long getDelay(TimeUnit unit); } diff --git a/classpath/java/util/concurrent/ExecutorService.java b/classpath/java/util/concurrent/ExecutorService.java index f963bdff05..684432abdb 100644 --- a/classpath/java/util/concurrent/ExecutorService.java +++ b/classpath/java/util/concurrent/ExecutorService.java @@ -14,6 +14,8 @@ import java.util.Collection; public interface ExecutorService extends Executor { public void shutdown(); + + public List shutdownNow(); public boolean isShutdown(); diff --git a/classpath/java/util/concurrent/Executors.java b/classpath/java/util/concurrent/Executors.java new file mode 100644 index 0000000000..cd959faf42 --- /dev/null +++ b/classpath/java/util/concurrent/Executors.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2008-2014, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.util.concurrent; + +public class Executors { + public static Callable callable(final Runnable task, final T result) { + return new Callable() { + @Override + public T call() throws Exception { + task.run(); + + return result; + } + }; + } +} From ee0ad22415236a5d6a44e4012bdd0d03a736e189 Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Mon, 15 Dec 2014 17:15:00 -0700 Subject: [PATCH 36/70] Undo my collections changes, as I was wrong here --- classpath/java/util/Collections.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java index 5267804e6c..e674982e16 100644 --- a/classpath/java/util/Collections.java +++ b/classpath/java/util/Collections.java @@ -38,11 +38,7 @@ public class Collections { public static void sort(List list) { sort(list, new Comparator() { public int compare(Object a, Object b) { - if (a instanceof Comparable) { - return ((Comparable) a).compareTo(b); - } else { - return a.hashCode() - b.hashCode(); - } + return ((Comparable) a).compareTo(b); } }); } From b3bd58aefff1ee073e16f36b033b3c3bf3ee0f15 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Fri, 5 Dec 2014 15:58:52 -0700 Subject: [PATCH 37/70] work in progress towards 64-bit ARM JIT support This won't build, it's just a snapshot of what I have so far. Conflicts: include/avian/codegen/architecture.h include/avian/codegen/registers.h src/codegen/compiler.cpp src/codegen/compiler/event.cpp src/codegen/compiler/site.cpp src/codegen/compiler/site.h src/codegen/registers.cpp src/codegen/target/arm/assembler.cpp src/codegen/target/arm/registers.h --- include/avian/codegen/architecture.h | 2 - src/codegen/compiler/site.h | 2 +- src/codegen/target/arm/assembler.cpp | 16 +- .../arm/{operations.cpp => operations32.cpp} | 4 + src/codegen/target/arm/operations64.cpp | 1218 +++++++++++++++++ src/codegen/target/arm/registers.h | 31 +- src/compile-arm.S | 120 +- 7 files changed, 1362 insertions(+), 31 deletions(-) rename src/codegen/target/arm/{operations.cpp => operations32.cpp} (99%) create mode 100644 src/codegen/target/arm/operations64.cpp diff --git a/include/avian/codegen/architecture.h b/include/avian/codegen/architecture.h index 47687aefaf..528be74858 100644 --- a/include/avian/codegen/architecture.h +++ b/include/avian/codegen/architecture.h @@ -28,8 +28,6 @@ namespace codegen { class Assembler; -class RegisterFile; - class OperandMask { public: uint8_t typeMask; diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index b2c10ddc39..5099704a34 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -123,7 +123,7 @@ class Site { virtual RegisterMask registerMask(Context*) { - return 0; + return RegisterMask(0); } virtual bool isVolatile(Context*) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index a6c7491279..23b07ef201 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -39,7 +39,7 @@ namespace isa { bool vfpSupported() { // TODO: Use at runtime detection -#if defined(__ARM_PCS_VFP) +#if (defined __ARM_PCS_VFP) || (defined ARCH_arm64) // armhf return true; #else @@ -55,9 +55,9 @@ bool vfpSupported() const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0); const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK); -const unsigned FrameHeaderSize = 1; +const unsigned FrameHeaderSize = TargetBytesPerWord / 4; -const unsigned StackAlignmentInBytes = 8; +const unsigned StackAlignmentInBytes = TargetBytesPerWord * 2; const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord; @@ -258,7 +258,7 @@ class MyArchitecture : public Architecture { virtual unsigned argumentRegisterCount() { - return 4; + return TargetBytesPerWord; } virtual Register argumentRegister(unsigned index) @@ -434,11 +434,11 @@ class MyArchitecture : public Architecture { break; case lir::Float2Int: - // todo: Java requires different semantics than SSE for + // todo: Java requires different semantics than VFP for // converting floats to integers, we we need to either use // thunks or produce inline machine code which handles edge // cases properly. - if (false && vfpSupported() && bSize == 4) { + if (false && vfpSupported() && bSize <= TargetBytesPerWord) { aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); } else { @@ -447,7 +447,7 @@ class MyArchitecture : public Architecture { break; case lir::Int2Float: - if (vfpSupported() && aSize == 4) { + if (vfpSupported() && aSize <= TargetBytesPerWord) { aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); } else { @@ -544,7 +544,7 @@ class MyArchitecture : public Architecture { case lir::ShiftLeft: case lir::ShiftRight: case lir::UnsignedShiftRight: - if (bSize == 8) + if (bSize > TargetBytesPerWord) aMask.typeMask = bMask.typeMask = lir::Operand::RegisterPairMask; break; diff --git a/src/codegen/target/arm/operations.cpp b/src/codegen/target/arm/operations32.cpp similarity index 99% rename from src/codegen/target/arm/operations.cpp rename to src/codegen/target/arm/operations32.cpp index 87d88613fd..5a9f5e8a0e 100644 --- a/src/codegen/target/arm/operations.cpp +++ b/src/codegen/target/arm/operations32.cpp @@ -15,6 +15,8 @@ #include "fixup.h" #include "multimethod.h" +#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM + namespace avian { namespace codegen { namespace arm { @@ -1554,3 +1556,5 @@ void storeLoadBarrier(Context* con) } // namespace arm } // namespace codegen } // namespace avian + +#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp new file mode 100644 index 0000000000..0f713645ad --- /dev/null +++ b/src/codegen/target/arm/operations64.cpp @@ -0,0 +1,1218 @@ +/* Copyright (c) 2008-2014, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include "context.h" +#include "operations.h" +#include "block.h" +#include "fixup.h" +#include "multimethod.h" + +#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 + +namespace { + +void append(Context* c, uint32_t instruction, unsigned size) +{ + c->code.append4(instruction | (size == 8 ? 0x80000000 : 0)); +} + +uint32_t lslv(int Rd, int Rn, int Rm, unsigned size) +{ + return (size == 8 ? 0x9ac12000 : 0x1ac02000) | (Rm << 16) | (Rn << 5) | Rd; +} + +uint32_t ubfm(int Rd, int Rn, int r, int s, unsigned size) +{ + return (size == 8 ? 0xd3608000 : 0x53000000) | (r << 16) | (s << 10) | (Rn << 5) | Rd; +} + +uint32_t sbfm(int Rd, int Rn, int r, int s, unsigned size) +{ + return (size == 8 ? 0x93408000 : 0x13000000) | (r << 16) | (s << 10) | (Rn << 5) | Rd; +} + +uint32_t lsli(int Rd, int Rn, int shift, unsigned size) +{ + if (size == 4) { + return ubfm(Rd, Rn, (32 - shift) & 0x1f, 31 - shift, size); + } else { + return ubfm(Rd, Rn, (64 - shift) & 0x3f, 63 - shift, size); + } +} + +uint32_t asrv(int Rd, int Rn, int Rm, unsigned size) +{ + return (size == 8 ? 0x9ac02800 : 0x1ac02800) | (Rm << 16) | (Rn << 5) | Rd; +} + +uint32_t lsrv(int Rd, int Rn, int Rm, unsigned size) +{ + return (size == 8 ? 0x9ac02400 : 0x1ac02400) | (Rm << 16) | (Rn << 5) | Rd; +} + +uint32_t lsri(int Rd, int Rn, int shift, unsigned size) +{ + return ubfm(Rd, Rn, shift, size == 8 ? 63 : 31, size); +} + +uint32_t asri(int Rd, int Rn, int shift, unsigned size) +{ + return sbfm(Rd, Rn, shift, size == 8 ? 63 : 31, size); +} + +uint32_t sxtb(int Rd, int Rn) +{ + return sbfm(Rd, Rn, 0, 7, 8); +} + +uint32_t sxth(int Rd, int Rn) +{ + return sbfm(Rd, Rn, 0, 15, 8); +} + +uint32_t uxth(int Rd, int Rn) +{ + return ubfm(Rd, Rn, 0, 15, 4); +} + +uint32_t sxtw(int Rd, int Rn) +{ + return sbfm(Rd, Rn, 0, 31, 8); +} + +uint32_t br(int Rn) +{ + return 0xd61f0000 | (Rn << 5); +} + +uint32_t fmovFdFn(int Fd, int Fn, unsigned size) +{ + return (size == 8 ? 0x1e604000 : 0x1e204000) | (Fn << 5) | Fd; +} + +uint32_t fmovRdFn(int Rd, int Fn, unsigned size) +{ + return (size == 8 ? 0x9e660000 : 0x1e260000) | (Fn << 5) | Rd; +} + +uint32_t fmovFdRn(int Fd, int Rn, unsigned size) +{ + return (size == 8 ? 0x9e670000 : 0x1e270000) | (Rn << 5) | Fd; +} + +uint32_t orr(int Rd, int Rn, int Rm, unsigned size) +{ + return (size == 8 ? 0xaa0003e0 : 0x2a0003e0) | (Rm << 16) | (Rn << 5) | Rd; +} + +uint32_t mov(int Rd, int Rn, unsigned size) +{ + return orr(Rd, 31, Rn, size); +} + +uint32_t ldrPCRel(int Rd, int offset, unsigned size) +{ + return (size == 8 ? 0x58000000 : 0x18000000) | (offset << 5) | Rd; +} + +uint32_t add(int Rd, int Rn, int Rm, unsigned size) +{ + return (size == 8 ? 0x8b000000 : 0x0b000000) | (Rm << 16) | (Rn << 5) | Rd; +} + +uint32_t sub(int Rd, int Rn, int Rm, unsigned size) +{ + return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm << 16) | (Rn << 5) | Rd; +} + +uint32_t madd(int Rd, int Rn, int Rm, int Ra, unsigned size) +{ + return (size == 8 ? 0x9b000000 : 0x1b000000) + | (Rm << 16) | (Ra << 10) | (Rn << 5) | Rd; +} + +uint32_t mul(int Rd, int Rn, int Rm, unsigned size) +{ + return madd(Rd, Rn, Rm, 31, size); +} + +uint32_t addi(int Rd, int Rn, int value, int shift, unsigned size) +{ + return (size == 8 ? 0x91000000 : 0x11000000) | (shift ? 0x400000 : 0) + | (value << 10) | (Rn << 5) | Rd; +} + +uint32_t subi(int Rd, int Rn, int value, int shift, unsigned size) +{ + return (size == 8 ? 0xd1000000 : 0x51000000) | (shift ? 0x400000 : 0) + | (value << 10) | (Rn << 5) | Rd; +} + +} // namespace + +namespace avian { +namespace codegen { +namespace arm { + +using namespace isa; +using namespace avian::util; + +void shiftLeftR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, lslv(dst->low, b->low, a->low, size)); +} + +void shiftLeftC(Context* c, + unsigned size, + lir::Constant* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + uint64_t value = a->value->value(); + if (size == 4 and (value & 0x1F)) { + append(c, lsli(dst->low, b->low, value, 4)); + } else (size == 8 and (value & 0x3F)) { + append(c, lsli(dst->low, b->low, value, 8)); + } else { + moveRR(c, size, b, size, dst); + } +} + +void shiftRightR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, asrv(dst->low, b->low, a->low, size)); +} + +void shiftRightC(Context* c, + unsigned size UNUSED, + lir::Constant* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + uint64_t value = a->value->value(); + if (size == 4 and (value & 0x1F)) { + append(c, lsri(dst->low, b->low, value, 4), 4); + } else (size == 8 and (value & 0x3F)) { + append(c, lsri(dst->low, b->low, value, 8), 8); + } else { + moveRR(c, size, b, size, dst); + } +} + +void unsignedShiftRightR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, lsrv(dst->low, b->low, a->low, size)); +} + +void unsignedShiftRightC(Context* c, + unsigned size UNUSED, + lir::Constant* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + uint64_t value = a->value->value(); + if (size == 4 and (value & 0x1F)) { + append(c, asri(dst->low, b->low, value, 4), 4); + } else (size == 8 and (value & 0x3F)) { + append(c, asri(dst->low, b->low, value, 8), 8); + } else { + moveRR(c, size, b, size, dst); + } +} + +void jumpR(Context* c, unsigned size UNUSED, lir::RegisterPair* target) +{ + assertT(c, size == vm::TargetBytesPerWord); + append(c, br(target->low)); +} + +void moveRR(Context* c, + unsigned srcSize, + lir::RegisterPair* src, + unsigned dstSize, + lir::RegisterPair* dst) +{ + bool srcIsFpr = isFpr(src); + bool dstIsFpr = isFpr(dst); + if (srcIsFpr or dstIsFpr) { + assertT(c, srcSize == dstSize); + + if (srcIsFpr and dstIsFpr) { + append(c, fmovFdFn(fpr(dst), fpr(src), srcSize)); + } else if (srcIsFpr) { + append(c, fmovRdFn(fpr(dst), fpr(src), srcSize)); + } else { + append(c, fmovFdRn(fpr(dst), fpr(src), srcSize)); + } + } else { + switch (srcSize) { + case 1: + append(c, sxtb(dst->low, src->low)); + break; + + case 2: + append(c, sxth(dst->low, src->low)); + break; + + case 4: + if (dstSize == 4) { + append(c, mov(dst->low, src->low, srcSize)); + } else { + append(c, sxtw(dst->low, src->low)); + } + break; + + case 8: + append(c, mov(dst->low, src->low, srcSize)); + break; + + default: + abort(c); + } + } +} + +void moveZRR(Context* c, + unsigned srcSize, + lir::RegisterPair* src, + unsigned, + lir::RegisterPair* dst) +{ + switch (srcSize) { + case 2: + aapend(c, uxth(dst->low, src->low)); + break; + + default: + abort(c); + } +} + +void moveCR2(Context* c, + unsigned size, + lir::Constant* src, + lir::RegisterPair* dst, + Promise* callOffset) +{ + if (isFpr(dst)) { + // todo: could use a single fmov here and avoid the temporary for + // constants that fit + lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + moveCR(c, size, src, size, &tmp); + moveRR(c, size, &tmp, size, dst); + c->client->releaseTemporary(tmp.low); + } else if (src->value->resolved()) { + int64_t value = src->value->value(); + if (value > 0) { + append(c, mov(dst->low, value & 0xFFFF)); + if (value >> 16) { + append(c, movk(dst->low, (value >> 16) & 0xFFFF), 16); + if (value >> 32) { + append(c, movk(dst->low, (value >> 32) & 0xFFFF), 32); + if (value >> 48) { + append(c, movk(dst->low, (value >> 48) & 0xFFFF), 48); + } + } + } + } else if (value < 0) { + append(c, movn(dst->low, (~value) & 0xFFFF)); + if (~(value >> 16)) { + append(c, movk(dst->low, (value >> 16) & 0xFFFF), 16); + if (~(value >> 32)) { + append(c, movk(dst->low, (value >> 32) & 0xFFFF), 32); + if (~(value >> 48)) { + append(c, movk(dst->low, (value >> 48) & 0xFFFF), 48); + } + } + } + } + } else { + appendConstantPoolEntry(c, src->value, callOffset); + append(c, ldrPCRel(dst->low, 0)); + } +} + +void moveCR(Context* c, + unsigned size, + lir::Constant* src, + unsigned, + lir::RegisterPair* dst) +{ + moveCR2(c, size, src, dst, 0); +} + +void addR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, add(dst, a, b, size)); +} + +void subR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, sub(dst, a, b, size)); +} + +void addC(Context* c, + unsigned size, + lir::Constant* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + int32_t v = a->value->value(); + if (v) { + if (v > 0 and v < 0x1000) { + append(c, addi(dst->low, b->low, v, 0, size)); + } else if (v > 0 and v < 0x1000000 and v % 0x1000 == 0) { + append(c, addi(dst->low, b->low, v >> 12, 12, size)); + } else { + // todo + abort(c); + } + } else { + moveRR(c, size, b, size, dst); + } +} + +void subC(Context* c, + unsigned size, + lir::Constant* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + int32_t v = a->value->value(); + if (v) { + if (v > 0 and v < 0x1000) { + append(c, subi(dst->low, b->low, v, 0, size)); + } else if (v > 0 and v < 0x1000000 and v % 0x1000 == 0) { + append(c, subi(dst->low, b->low, v >> 12, 12, size)); + } else { + // todo + abort(c); + } + } else { + moveRR(c, size, b, size, dst); + } +} + +void multiplyR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, mul(dst->low, a->low, b->low)); +} + +void floatAbsoluteRR(Context* c, + unsigned size, + lir::RegisterPair* a, + unsigned, + lir::RegisterPair* b) +{ + append(c, fabs(fpr(b), fpr(a), size)); +} + +void floatNegateRR(Context* c, + unsigned size, + lir::RegisterPair* a, + unsigned, + lir::RegisterPair* b) +{ + append(c, fneg(fpr(b), fpr(a), size)); +} + +void float2FloatRR(Context* c, + unsigned size, + lir::RegisterPair* a, + unsigned, + lir::RegisterPair* b) +{ + if (size == 8) { + append(c, fcvtSdDn(fpr(b), fpr(a))); + } else { + append(c, fcvtDdSn(fpr(b), fpr(a))); + } +} + +void float2IntRR(Context* c, + unsigned size, + lir::RegisterPair* a, + unsigned, + lir::RegisterPair* b) +{ + if (size == 8) { + append(c, fcvtasWdDn(b->low, fpr(a))); + } else { + append(c, fcvtasWdSn(b->low, fpr(a))); + } +} + +void int2FloatRR(Context* c, + unsigned, + lir::RegisterPair* a, + unsigned size, + lir::RegisterPair* b) +{ + if (size == 8) { + append(c, scvtfDdWn(fpr(b), b->low)); + } else { + append(c, scvtfSdWn(fpr(b), b->low)); + } +} + +void floatSqrtRR(Context* c, + unsigned size, + lir::RegisterPair* a, + unsigned, + lir::RegisterPair* b) +{ + append(c, fsqrt(fpr(b), fpr(a), size)); +} + +void floatAddR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, fadd(fpr, dst, fpr(b), fpr(a), size)); +} + +void floatSubtractR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, fsub(fpr, dst, fpr(b), fpr(a), size)); +} + +void floatMultiplyR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, fmul(fpr, dst, fpr(b), fpr(a), size)); +} + +void floatDivideR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, fdiv(fpr, dst, fpr(b), fpr(a), size)); +} + +int normalize(Context* c, + int offset, + int index, + unsigned scale, + bool* preserveIndex, + bool* release) +{ + if (offset != 0 or scale != 1) { + lir::Register normalizedIndex( + *preserveIndex ? con->client->acquireTemporary(GPR_MASK) : index); + + if (*preserveIndex) { + *release = true; + *preserveIndex = false; + } else { + *release = false; + } + + int scaled; + + if (scale != 1) { + lir::Register unscaledIndex(index); + + ResolvedPromise scalePromise(log(scale)); + lir::Constant scaleConstant(&scalePromise); + + shiftLeftC(c, + vm::TargetBytesPerWord, + &scaleConstant, + &unscaledIndex, + &normalizedIndex); + + scaled = normalizedIndex.low; + } else { + scaled = index; + } + + if (offset != 0) { + lir::Register untranslatedIndex(scaled); + + ResolvedPromise offsetPromise(offset); + lir::Constant offsetConstant(&offsetPromise); + + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + moveCR(c, + vm::TargetBytesPerWord, + &offsetConstant, + vm::TargetBytesPerWord, + &tmp); + addR(c, + vm::TargetBytesPerWord, + &tmp, + &untranslatedIndex, + &normalizedIndex); + con->client->releaseTemporary(tmp.low); + } + + return normalizedIndex.low; + } else { + *release = false; + return index; + } +} + +void store(Context* c, + unsigned size, + lir::RegisterPair* src, + int base, + int offset, + int index, + unsigned scale, + bool preserveIndex) +{ + if (index != lir::NoRegister) { + bool release; + int normalized + = normalize(c, offset, index, scale, &preserveIndex, &release); + + if (isFpr(src)) { + switch (size) { + case 4: + case 8: + append(c, strFs(fpr(src->low), base, normalized, size)); + break; + + default: + abort(c); + } + } else { + switch (size) { + case 1: + append(c, strb(src->low, base, normalized)); + break; + + case 2: + append(c, strh(src->low, base, normalized)); + break; + + case 4: + case 8: + append(c, str(src->low, base, normalized, size)); + break; + + default: + abort(c); + } + } + + if (release) { + c->client->releaseTemporary(normalized); + } + } else if (abs(offset) == (abs(offset) & 0xFF)) { + if (isFpr(src)) { + switch (size) { + case 4: + case 8: + append(c, striFs(fpr(src->low), base, offset, size)); + break; + + default: + abort(c); + } + } else { // FPR store + switch (size) { + case 1: + append(c, strbi(src->low, base, offset)); + break; + + case 2: + append(c, strhi(src->low, base, offset)); + break; + + case 4: + case 8: + append(c, stri(src->low, base, offset, size)); + break; + + default: + abort(c); + } + } + } else { + lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + ResolvedPromise offsetPromise(offset); + lir::Constant offsetConstant(&offsetPromise); + moveCR(c, + vm::TargetBytesPerWord, + &offsetConstant, + vm::TargetBytesPerWord, + &tmp); + + store(c, size, src, base, 0, tmp.low, 1, false); + + c->client->releaseTemporary(tmp.low); + } +} + +void moveRM(Context* c, + unsigned srcSize, + lir::RegisterPair* src, + unsigned dstSize UNUSED, + lir::Memory* dst) +{ + assertT(c, srcSize == dstSize); + + store( + c, srcSize, src, dst->base, dst->offset, dst->index, dst->scale, true); +} + +void load(Context* c, + unsigned srcSize, + int base, + int offset, + int index, + unsigned scale, + unsigned dstSize, + lir::RegisterPair* dst, + bool preserveIndex, + bool signExtend) +{ + if (index != lir::NoRegister) { + bool release; + int normalized + = normalize(c, offset, index, scale, &preserveIndex, &release); + + if (isFpr(dst)) { // FPR load + switch (srcSize) { + case 4: + case 8: + append(c, ldrFd(fpr(dst->low), base, normalized, srcSize)); + break; + + default: + abort(c); + } + } else { + switch (srcSize) { + case 1: + if (signExtend) { + append(c, ldrsb(dst->low, base, normalized)); + } else { + append(c, ldrb(dst->low, base, normalized)); + } + break; + + case 2: + if (signExtend) { + append(c, ldrsh(dst->low, base, normalized)); + } else { + append(c, ldrh(dst->low, base, normalized)); + } + break; + + case 4: + case 8: + if (signExtend and srcSize == 4 and dstSize == 8) { + append(c, ldrsw(dst->low, base, normalized)); + } else { + append(c, ldr(dst->low, base, normalized, srcSize)); + } + break; + + default: + abort(c); + } + } + + if (release) { + c->client->releaseTemporary(normalized); + } + } else if (abs(offset) == (abs(offset) & 0xFF)) { + if (isFpr(dst)) { + switch (srcSize) { + case 4: + case 8: + append(c, ldriFd(fpr(dst->low), base, offset)); + break; + + default: + abort(c); + } + } else { + switch (srcSize) { + case 1: + if (signExtend) { + append(c, ldrsbi(dst->low, base, offset)); + } else { + append(c, ldrbi(dst->low, base, offset)); + } + break; + + case 2: + if (signExtend) { + append(c, ldrshi(dst->low, base, offset)); + } else { + append(c, ldrhi(dst->low, base, offset)); + } + break; + + case 4: + case 8: + if (signExtend and srcSize == 4 and dstSize == 8) { + append(c, ldrswi(dst->low, base, offset)); + } else { + append(c, ldri(dst->low, base, offset, size)); + } + break; + + default: + abort(c); + } + } + } else { + lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + ResolvedPromise offsetPromise(offset); + lir::Constant offsetConstant(&offsetPromise); + moveCR(c, + vm::TargetBytesPerWord, + &offsetConstant, + vm::TargetBytesPerWord, + &tmp); + + load(c, srcSize, base, 0, tmp.low, 1, dstSize, dst, false, signExtend); + + c->client->releaseTemporary(tmp.low); + } +} + +void moveMR(Context* c, + unsigned srcSize, + lir::Memory* src, + unsigned dstSize, + lir::RegisterPair* dst) +{ + load(c, + srcSize, + src->base, + src->offset, + src->index, + src->scale, + dstSize, + dst, + true, + true); +} + +void moveZMR(Context* c, + unsigned srcSize, + lir::Memory* src, + unsigned dstSize, + lir::RegisterPair* dst) +{ + load(c, + srcSize, + src->base, + src->offset, + src->index, + src->scale, + dstSize, + dst, + true, + false); +} + +void andR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, and_(dst->low, a->low, b->low, size)); +} + +void andC(Context* c, + unsigned size, + lir::Constant* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + int64_t v = a->value->value(); + + if (~v) { + bool useTemporary = b->low == dst->low; + lir::Register tmp(dst->low); + if (useTemporary) { + tmp.low = c->client->acquireTemporary(GPR_MASK); + } + + moveCR(c, size, a, size, &tmp); + andR(c, size, b, &tmp, dst); + + if (useTemporary) { + c->client->releaseTemporary(tmp.low); + } + } else { + moveRR(c, size, b, size, dst); + } +} + +void orR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, orr(dst->low, a->low, b->low, size)); +} + +void xorR(Context* c, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::RegisterPair* dst) +{ + append(c, eor(dst->low, a->low, b->low, size)); +} + +void moveAR(Context* c, + unsigned srcSize, + lir::Address* src, + unsigned dstSize, + lir::RegisterPair* dst) +{ + assertT(c, srcSize == TargetBytesPerWord and dstSize == TargetBytesPerWord); + + lir::Constant constant(src->address); + moveCR(c, srcSize, &constant, dstSize, dst); + + lir::Memory memory(dst->low, 0, -1, 0); + moveMR(c, dstSize, &memory, dstSize, dst); +} + +void compareRR(Context* c, + unsigned aSize, + lir::RegisterPair* a, + unsigned bSize UNUSED, + lir::RegisterPair* b) +{ + assertT(c, not (isFpr(a) xor isFpr(b))); + assertT(c, aSize == bSize); + + if (isFpr(a)) { + append(c, fcmp(fpr(b), fpr(a), aSize)); + } else { + append(c, cmp(b->low, a->low, aSize)); + } +} + +void compareCR(Context* c, + unsigned aSize, + lir::Constant* a, + unsigned bSize, + lir::RegisterPair* b) +{ + assertT(c, aSize == bSize); + + int32_t v = a->value->value(); + if (v) { + if (v > 0 and v < 0x1000) { + append(c, cmpi(b->low, v, 0, size)); + } else if (v > 0 and v < 0x1000000 and v % 0x1000 == 0) { + append(c, cmpi(b->low, v >> 12, 12, size)); + } else { + // todo + abort(c); + } + } +} + +void compareCM(Context* c, + unsigned aSize, + lir::Constant* a, + unsigned bSize, + lir::Memory* b) +{ + assertT(c, aSize == bSize); + + lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + moveMR(c, bSize, b, bSize, &tmp); + compareCR(c, aSize, a, bSize, &tmp); + c->client->releaseTemporary(tmp.low); +} + +void compareRM(Context* c, + unsigned aSize, + lir::RegisterPair* a, + unsigned bSize, + lir::Memory* b) +{ + assertT(c, aSize == bSize); + + lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + moveMR(c, bSize, b, bSize, &tmp); + compareRR(c, aSize, a, bSize, &tmp); + c->client->releaseTemporary(tmp.low); +} + +int32_t branch(Context* c, lir::TernaryOperation op) +{ + switch (op) { + case lir::JumpIfEqual: + case lir::JumpIfFloatEqual: + return beq(0); + + case lir::JumpIfNotEqual: + case lir::JumpIfFloatNotEqual: + return bne(0); + + case lir::JumpIfLess: + case lir::JumpIfFloatLess: + case lir::JumpIfFloatLessOrUnordered: + return blt(0); + + case lir::JumpIfGreater: + case lir::JumpIfFloatGreater: + return bgt(0); + + case lir::JumpIfLessOrEqual: + case lir::JumpIfFloatLessOrEqual: + case lir::JumpIfFloatLessOrEqualOrUnordered: + return ble(0); + + case lir::JumpIfGreaterOrEqual: + case lir::JumpIfFloatGreaterOrEqual: + return bge(0); + + case lir::JumpIfFloatGreaterOrUnordered: + return bhi(0); + + case lir::JumpIfFloatGreaterOrEqualOrUnordered: + return bpl(0); + + default: + abort(c); + } +} + +void conditional(Context* c, int32_t branch, lir::Constant* target) +{ + appendOffsetTask(c, target->value, offsetPromise(con)); + append(c, branch); +} + +void branch(Context* c, lir::TernaryOperation op, lir::Constant* target) +{ + conditional(c, branch(c, op), target); +} + +void branchRR(Context* c, + lir::TernaryOperation op, + unsigned size, + lir::RegisterPair* a, + lir::RegisterPair* b, + lir::Constant* target) +{ + compareRR(c, size, a, size, b); + branch(c, op, target); +} + +void branchCR(Context* c, + lir::TernaryOperation op, + unsigned size, + lir::Constant* a, + lir::RegisterPair* b, + lir::Constant* target) +{ + assertT(c, not isFloatBranch(op)); + + compareCR(c, size, a, size, b); + branch(c, op, target); +} + +void branchRM(Context* c, + lir::TernaryOperation op, + unsigned size, + lir::RegisterPair* a, + lir::Memory* b, + lir::Constant* target) +{ + assertT(c, not isFloatBranch(op)); + assertT(c, size <= vm::TargetBytesPerWord); + + compareRM(c, size, a, size, b); + branch(c, op, target); +} + +void branchCM(Context* c, + lir::TernaryOperation op, + unsigned size, + lir::Constant* a, + lir::Memory* b, + lir::Constant* target) +{ + assertT(c, not isFloatBranch(op)); + assertT(c, size <= vm::TargetBytesPerWord); + + compareCM(c, size, a, size, b); + branch(c, op, target); +} + +ShiftMaskPromise* shiftMaskPromise(Context* c, + Promise* base, + unsigned shift, + int64_t mask) +{ + return new (con->zone) ShiftMaskPromise(base, shift, mask); +} + +void moveCM(Context* c, + unsigned srcSize, + lir::Constant* src, + unsigned dstSize, + lir::Memory* dst) +{ + switch (dstSize) { + case 8: { + lir::Constant srcHigh(shiftMaskPromise(c, src->value, 32, 0xFFFFFFFF)); + lir::Constant srcLow(shiftMaskPromise(c, src->value, 0, 0xFFFFFFFF)); + + lir::Memory dstLow(dst->base, dst->offset + 4, dst->index, dst->scale); + + moveCM(c, 4, &srcLow, 4, &dstLow); + moveCM(c, 4, &srcHigh, 4, dst); + } break; + + default: + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + moveCR(c, srcSize, src, dstSize, &tmp); + moveRM(c, dstSize, &tmp, dstSize, dst); + con->client->releaseTemporary(tmp.low); + } +} + +void negateRR(Context* c, + unsigned srcSize, + lir::RegisterPair* src, + unsigned dstSize UNUSED, + lir::RegisterPair* dst) +{ + assertT(c, srcSize == dstSize); + + append(c, neg(dst->low, src->low, srcSize)); +} + +void callR(Context* c, unsigned size UNUSED, lir::RegisterPair* target) +{ + assertT(c, size == vm::TargetBytesPerWord); + append(c, blr(target->low)); +} + +void callC(Context* c, unsigned size UNUSED, lir::Constant* target) +{ + assertT(c, size == vm::TargetBytesPerWord); + + appendOffsetTask(c, target->value, offsetPromise(c)); + append(c, bl(0)); +} + +void longCallC(Context* c, unsigned size UNUSED, lir::Constant* target) +{ + assertT(c, size == vm::TargetBytesPerWord); + + lir::Register tmp(9); // a non-arg reg that we don't mind clobbering + moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c)); + callR(c, vm::TargetBytesPerWord, &tmp); +} + +void longJumpC(Context* c, unsigned size UNUSED, lir::Constant* target) +{ + assertT(c, size == vm::TargetBytesPerWord); + + lir::Register tmp(9); // a non-arg reg that we don't mind clobbering + moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c)); + jumpR(c, vm::TargetBytesPerWord, &tmp); +} + +void jumpC(Context* c, unsigned size UNUSED, lir::Constant* target) +{ + assertT(c, size == vm::TargetBytesPerWord); + + appendOffsetTask(c, target->value, offsetPromise(c)); + append(c, b(0)); +} + +void return_(Context* c) +{ + append(c, br(LinkRegister)); +} + +void trap(Context* c) +{ + append(c, brk(0)); +} + +// todo: determine the minimal operation types and domains needed to +// implement the following barriers (see +// http://community.arm.com/groups/processors/blog/2011/10/19/memory-access-ordering-part-3--memory-access-ordering-in-the-arm-architecture). +// For now, we just use DMB SY as a conservative but not necessarily +// performant choice. + +void memoryBarrier(Context* c) +{ + append(c, dmb()); +} + +void loadBarrier(Context* c) +{ + memoryBarrier(c); +} + +void storeStoreBarrier(Context* c) +{ + memoryBarrier(c); +} + +void storeLoadBarrier(Context* c) +{ + memoryBarrier(c); +} + +} // namespace arm +} // namespace codegen +} // namespace avian + +#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index ad13db466a..476cff546f 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -21,10 +21,29 @@ namespace arm { const uint64_t MASK_LO32 = 0xffffffff; const unsigned MASK_LO8 = 0xff; +#ifdef ARCH_arm64 +constexpr Register ThreadRegister(19); +constexpr Register StackRegister(31); +constexpr Register LinkRegister(30); +constexpr Register LinkRegister(29); +constexpr Register ProgramCounter(0xFE); // i.e. unaddressable + +const int N_GPRS = 32; +const int N_FPRS = 32; +const uint64_t GPR_MASK = 0xffffffff; +const uint64_t FPR_MASK = 0xffffffff00000000; +#else +constexpr Register ThreadRegister(8); +constexpr Register StackRegister(13); +constexpr Register LinkRegister(14); +constexpr Register FrameRegister(0xFE); // i.e. there is none +constexpr Register ProgramCounter(15); + const int N_GPRS = 16; const int N_FPRS = 16; const RegisterMask GPR_MASK = 0xffff; const RegisterMask FPR_MASK = 0xffff0000; +#endif inline bool isFpr(lir::RegisterPair* reg) { @@ -48,18 +67,6 @@ inline int fpr32(lir::RegisterPair* reg) return fpr64(reg) << 1; } -#ifdef ARCH_arm64 -constexpr Register ThreadRegister(19); -constexpr Register StackRegister(31); -constexpr Register LinkRegister(30); -constexpr Register ProgramCounter(0xFE); // i.e. unaddressable -#else -constexpr Register ThreadRegister(8); -constexpr Register StackRegister(13); -constexpr Register LinkRegister(14); -constexpr Register ProgramCounter(15); -#endif - } // namespace arm } // namespace codegen } // namespace avian diff --git a/src/compile-arm.S b/src/compile-arm.S index 37b61da454..432b79e646 100644 --- a/src/compile-arm.S +++ b/src/compile-arm.S @@ -16,20 +16,122 @@ #define BYTES_PER_WORD 4 #define LOCAL(x) .L##x - + #ifdef __APPLE__ # define GLOBAL(x) _##x #else -# define GLOBAL(x) x +# define GLOBAL(x) x #endif +#ifdef __aarch64__ + +.globl GLOBAL(vmInvoke) +.align 2 +GLOBAL(vmInvoke): + // arguments: + // x0 : thread + // x1 : function + // x2 : arguments + // w3 : argumentFootprint + // w4 : frameSize (not used) + // w5 : returnType + + // allocate frame + stp x29, x30, [sp,#-96]! + + // save callee-saved register values + stp x19, x20, [sp,#16] + stp x21, x22, [sp,#32] + stp x23, x24, [sp,#48] + stp x25, x26, [sp,#64] + stp x27, x28, [sp,#80] + + // save return type + str w5, [sp,#-16]! + + mov x5, sp + str x5, [x0,#TARGET_THREAD_SCRATCH] + + // copy arguments into place + sub sp, sp, w3 + mov x5, #0 + b LOCAL(vmInvoke_argumentTest) + +LOCAL(vmInvoke_argumentLoop): + ldr x5, [x2, x4] + str x5, [sp, x4] + add x4, x4, #BYTES_PER_WORD + +LOCAL(vmInvoke_argumentTest): + cmp x4, x3 + blt LOCAL(vmInvoke_argumentLoop) + + // we use x19 to hold the thread pointer, by convention + mov x19, x0 + + // load and call function address + blr x1 + +.globl GLOBAL(vmInvoke_returnAddress) +.align 2 +GLOBAL(vmInvoke_returnAddress): + // restore stack pointer + ldr x5, [x19, #TARGET_THREAD_SCRATCH] + mov sp, x5 + + // clear MyThread::stack to avoid confusing another thread calling + // java.lang.Thread.getStackTrace on this one. See + // MyProcess::getStackTrace in compile.cpp for details on how we get + // a reliable stack trace from a thread that might be interrupted at + // any point in its execution. + mov x5, #0 + str x5, [x19, #TARGET_THREAD_STACK] + +.globl GLOBAL(vmInvoke_safeStack) +.align 2 +GLOBAL(vmInvoke_safeStack): + +#ifdef AVIAN_CONTINUATIONS +#error todo +#endif // AVIAN_CONTINUATIONS + + mov x5, #0 + str x5, [x19, #TARGET_THREAD_STACK] + + // restore return type + ldr w5, [sp], #4 + + // restore callee-saved register values + ldp x19, x20, [sp,#16] + ldp x21, x22, [sp,#32] + ldp x23, x24, [sp,#48] + ldp x25, x26, [sp,#64] + ldp x27, x28, [sp,#80] + ldp x29, x30, [sp],#96 + +LOCAL(vmInvoke_return): + br x30 + +.globl GLOBAL(vmJumpAndInvoke) +.align 2 +GLOBAL(vmJumpAndInvoke): +#ifdef AVIAN_CONTINUATIONS +#error todo +#else // not AVIAN_CONTINUATIONS + // vmJumpAndInvoke should only be called when continuations are + // enabled, so we force a crash if we reach here: + brk 0 +#endif // not AVIAN_CONTINUATIONS + +#elif defined __arm__ + #define CONTINUATION_NEXT 4 #define CONTINUATION_ADDRESS 16 #define CONTINUATION_RETURN_ADDRESS_OFFSET 20 #define CONTINUATION_FRAME_POINTER_OFFSET 24 #define CONTINUATION_LENGTH 28 #define CONTINUATION_BODY 32 - + .globl GLOBAL(vmInvoke) .align 2 GLOBAL(vmInvoke): @@ -56,7 +158,7 @@ GLOBAL(vmInvoke): eor r4, sp, r3 tst r4, #4 subne sp, sp, #4 - + // copy arguments into place sub sp, r3 mov r4, #0 @@ -87,7 +189,7 @@ LOCAL(vmInvoke_argumentTest): GLOBAL(vmInvoke_returnAddress): // restore stack pointer ldr sp, [r8, #TARGET_THREAD_SCRATCH] - + // clear MyThread::stack to avoid confusing another thread calling // java.lang.Thread.getStackTrace on this one. See // MyProcess::getStackTrace in compile.cpp for details on how we get @@ -201,7 +303,7 @@ GLOBAL(vmJumpAndInvoke): // which is not true in this case sub r2,r2,r6 sub r2,r2,#84 - + mov r8,r0 // copy arguments into place @@ -220,7 +322,7 @@ LOCAL(vmJumpAndInvoke_argumentTest): // the arguments have been copied, so we can set the real stack // pointer now mov sp,r2 - + // set return address to vmInvoke_returnAddress #ifdef __APPLE__ movw r11, :lower16:(GLOBAL(vmInvoke_returnAddress)-(LOCAL(vmJumpAndInvoke_getAddress)+8)) @@ -246,10 +348,12 @@ LOCAL(vmInvoke_getAddress_word): LOCAL(vmJumpAndInvoke_getAddress_word): .word _GLOBAL_OFFSET_TABLE_-(LOCAL(vmJumpAndInvoke_getAddress)+8) #endif // not __APPLE__ - + #else // not AVIAN_CONTINUATIONS // vmJumpAndInvoke should only be called when continuations are // enabled, so we force a crash if we reach here: mov r1,#0 ldr r1,[r1] #endif // not AVIAN_CONTINUATIONS + +#endif // __arm__ From 123570515f512acb178a5e80a82eefae069f715e Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 8 Dec 2014 14:07:11 -0700 Subject: [PATCH 38/70] snapshot of ARM64 instruction encoding work Still not building, but more progress. --- src/codegen/target/arm/operations64.cpp | 99 ++++++++++++++++++------- src/codegen/target/arm/registers.h | 26 +++++-- 2 files changed, 92 insertions(+), 33 deletions(-) diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 0f713645ad..174642cb2f 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -18,9 +18,11 @@ namespace { -void append(Context* c, uint32_t instruction, unsigned size) +using namespace avian::codegen::arm; + +void append(Context* c, uint32_t instruction) { - c->code.append4(instruction | (size == 8 ? 0x80000000 : 0)); + c->code.append4(instruction); } uint32_t lslv(int Rd, int Rn, int Rm, unsigned size) @@ -117,6 +119,24 @@ uint32_t mov(int Rd, int Rn, unsigned size) return orr(Rd, 31, Rn, size); } +uint32_t movz(int Rd, int value, unsigned shift, unsigned size) +{ + return (size == 8 ? 0xd2800000 : 0x52800000) | ((shift >> 4) << 21) + | (value << 5) | Rd; +} + +uint32_t movn(int Rd, int value, unsigned shift, unsigned size) +{ + return (size == 8 ? 0x92800000 : 0x12800000) | ((shift >> 4) << 21) + | (value << 5) | Rd; +} + +uint32_t movk(int Rd, int value, unsigned shift, unsigned size) +{ + return (size == 8 ? 0xf2800000 : 0x72800000) | ((shift >> 4) << 21) + | (value << 5) | Rd; +} + uint32_t ldrPCRel(int Rd, int offset, unsigned size) { return (size == 8 ? 0x58000000 : 0x18000000) | (offset << 5) | Rd; @@ -155,13 +175,42 @@ uint32_t subi(int Rd, int Rn, int value, int shift, unsigned size) | (value << 10) | (Rn << 5) | Rd; } +uint32_t fabs(int Fd, int Fn, unsigned size) +{ + return (size == 8 ? 0x1e60c000 : 0x1e20c000) | (Fn << 5) | Fd; +} + +uint32_t fneg(int Fd, int Fn, unsigned size) +{ + return (size == 8 ? 0x1e614000 : 0x1e214000) | (Fn << 5) | Fd; +} + +uint32_t fcvtSdDn(int Fd, int Fn) +{ + return 0x1e624000 | (Fn << 5) | Fd; +} + +uint32_t fcvtDdSn(int Fd, int Fn) +{ + return 0x1e22c000 | (Fn << 5) | Fd; +} + +uint32_t fcvtasXdDn(int Rd, int Fn) +{ + return 0x9e640000 | (Fn << 5) | Rd; +} + +uint32_t fcvtasWdSn(int Rd, int Fn) +{ + return 0x1e240000 | (Fn << 5) | Rd; +} + } // namespace namespace avian { namespace codegen { namespace arm { -using namespace isa; using namespace avian::util; void shiftLeftR(Context* c, @@ -182,7 +231,7 @@ void shiftLeftC(Context* c, uint64_t value = a->value->value(); if (size == 4 and (value & 0x1F)) { append(c, lsli(dst->low, b->low, value, 4)); - } else (size == 8 and (value & 0x3F)) { + } else if (size == 8 and (value & 0x3F)) { append(c, lsli(dst->low, b->low, value, 8)); } else { moveRR(c, size, b, size, dst); @@ -206,9 +255,9 @@ void shiftRightC(Context* c, { uint64_t value = a->value->value(); if (size == 4 and (value & 0x1F)) { - append(c, lsri(dst->low, b->low, value, 4), 4); - } else (size == 8 and (value & 0x3F)) { - append(c, lsri(dst->low, b->low, value, 8), 8); + append(c, lsri(dst->low, b->low, value, 4)); + } else if (size == 8 and (value & 0x3F)) { + append(c, lsri(dst->low, b->low, value, 8)); } else { moveRR(c, size, b, size, dst); } @@ -231,9 +280,9 @@ void unsignedShiftRightC(Context* c, { uint64_t value = a->value->value(); if (size == 4 and (value & 0x1F)) { - append(c, asri(dst->low, b->low, value, 4), 4); - } else (size == 8 and (value & 0x3F)) { - append(c, asri(dst->low, b->low, value, 8), 8); + append(c, asri(dst->low, b->low, value, 4)); + } else if (size == 8 and (value & 0x3F)) { + append(c, asri(dst->low, b->low, value, 8)); } else { moveRR(c, size, b, size, dst); } @@ -299,7 +348,7 @@ void moveZRR(Context* c, { switch (srcSize) { case 2: - aapend(c, uxth(dst->low, src->low)); + append(c, uxth(dst->low, src->low)); break; default: @@ -323,31 +372,31 @@ void moveCR2(Context* c, } else if (src->value->resolved()) { int64_t value = src->value->value(); if (value > 0) { - append(c, mov(dst->low, value & 0xFFFF)); + append(c, movz(dst->low, value & 0xFFFF, 0, size)); if (value >> 16) { - append(c, movk(dst->low, (value >> 16) & 0xFFFF), 16); + append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); if (value >> 32) { - append(c, movk(dst->low, (value >> 32) & 0xFFFF), 32); + append(c, movk(dst->low, (value >> 32) & 0xFFFF, 32, size)); if (value >> 48) { - append(c, movk(dst->low, (value >> 48) & 0xFFFF), 48); + append(c, movk(dst->low, (value >> 48) & 0xFFFF, 48, size)); } } } } else if (value < 0) { - append(c, movn(dst->low, (~value) & 0xFFFF)); + append(c, movn(dst->low, (~value) & 0xFFFF, 0, size)); if (~(value >> 16)) { - append(c, movk(dst->low, (value >> 16) & 0xFFFF), 16); + append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); if (~(value >> 32)) { - append(c, movk(dst->low, (value >> 32) & 0xFFFF), 32); + append(c, movk(dst->low, (value >> 32) & 0xFFFF, 32, size)); if (~(value >> 48)) { - append(c, movk(dst->low, (value >> 48) & 0xFFFF), 48); + append(c, movk(dst->low, (value >> 48) & 0xFFFF, 48, size)); } } } } } else { appendConstantPoolEntry(c, src->value, callOffset); - append(c, ldrPCRel(dst->low, 0)); + append(c, ldrPCRel(dst->low, 0, size)); } } @@ -366,7 +415,7 @@ void addR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, add(dst, a, b, size)); + append(c, add(dst->low, a->low, b->low, size)); } void subR(Context* c, @@ -375,7 +424,7 @@ void subR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, sub(dst, a, b, size)); + append(c, sub(dst->low, a->low, b->low, size)); } void addC(Context* c, @@ -426,7 +475,7 @@ void multiplyR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, mul(dst->low, a->low, b->low)); + append(c, mul(dst->low, a->low, b->low, size)); } void floatAbsoluteRR(Context* c, @@ -435,7 +484,7 @@ void floatAbsoluteRR(Context* c, unsigned, lir::RegisterPair* b) { - append(c, fabs(fpr(b), fpr(a), size)); + append(c, fabs_(fpr(b), fpr(a), size)); } void floatNegateRR(Context* c, @@ -467,7 +516,7 @@ void float2IntRR(Context* c, lir::RegisterPair* b) { if (size == 8) { - append(c, fcvtasWdDn(b->low, fpr(a))); + append(c, fcvtasXdDn(b->low, fpr(a))); } else { append(c, fcvtasWdSn(b->low, fpr(a))); } diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index 476cff546f..da2d7151fd 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -30,8 +30,18 @@ constexpr Register ProgramCounter(0xFE); // i.e. unaddressable const int N_GPRS = 32; const int N_FPRS = 32; -const uint64_t GPR_MASK = 0xffffffff; -const uint64_t FPR_MASK = 0xffffffff00000000; +const RegisterMask GPR_MASK = 0xffffffff; +const RegisterMask FPR_MASK = 0xffffffff00000000; + +inline int fpr(int reg) +{ + return reg - N_GPRS; +} + +inline int fpr(lir::RegisterPair* reg) +{ + return fpr(reg->low); +} #else constexpr Register ThreadRegister(8); constexpr Register StackRegister(13); @@ -43,12 +53,6 @@ const int N_GPRS = 16; const int N_FPRS = 16; const RegisterMask GPR_MASK = 0xffff; const RegisterMask FPR_MASK = 0xffff0000; -#endif - -inline bool isFpr(lir::RegisterPair* reg) -{ - return reg->low.index() >= N_GPRS; -} inline int fpr64(Register reg) { @@ -66,6 +70,12 @@ inline int fpr32(lir::RegisterPair* reg) { return fpr64(reg) << 1; } +#endif + +inline bool isFpr(lir::RegisterPair* reg) +{ + return reg->low.index() >= N_GPRS; +} } // namespace arm } // namespace codegen From a6e88a8faa52f7f11a5bc65aba17ca886935590f Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 10 Dec 2014 13:52:30 -0700 Subject: [PATCH 39/70] fix some merge-introduced problems --- src/codegen/target/arm/operations64.cpp | 128 ++++++++++++------------ src/codegen/target/arm/registers.h | 9 -- 2 files changed, 66 insertions(+), 71 deletions(-) diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 174642cb2f..724f856d13 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -16,31 +16,41 @@ #if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 -namespace { +namespace avian { +namespace codegen { +namespace arm { -using namespace avian::codegen::arm; +inline int fpr(Register reg) +{ + return reg.index() - N_GPRS; +} + +inline int fpr(lir::RegisterPair* reg) +{ + return fpr(reg->low); +} void append(Context* c, uint32_t instruction) { c->code.append4(instruction); } -uint32_t lslv(int Rd, int Rn, int Rm, unsigned size) +uint32_t lslv(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x9ac12000 : 0x1ac02000) | (Rm << 16) | (Rn << 5) | Rd; + return (size == 8 ? 0x9ac12000 : 0x1ac02000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } -uint32_t ubfm(int Rd, int Rn, int r, int s, unsigned size) +uint32_t ubfm(Register Rd, Register Rn, int r, int s, unsigned size) { - return (size == 8 ? 0xd3608000 : 0x53000000) | (r << 16) | (s << 10) | (Rn << 5) | Rd; + return (size == 8 ? 0xd3608000 : 0x53000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); } -uint32_t sbfm(int Rd, int Rn, int r, int s, unsigned size) +uint32_t sbfm(Register Rd, Register Rn, int r, int s, unsigned size) { - return (size == 8 ? 0x93408000 : 0x13000000) | (r << 16) | (s << 10) | (Rn << 5) | Rd; + return (size == 8 ? 0x93408000 : 0x13000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); } -uint32_t lsli(int Rd, int Rn, int shift, unsigned size) +uint32_t lsli(Register Rd, Register Rn, int shift, unsigned size) { if (size == 4) { return ubfm(Rd, Rn, (32 - shift) & 0x1f, 31 - shift, size); @@ -49,49 +59,49 @@ uint32_t lsli(int Rd, int Rn, int shift, unsigned size) } } -uint32_t asrv(int Rd, int Rn, int Rm, unsigned size) +uint32_t asrv(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x9ac02800 : 0x1ac02800) | (Rm << 16) | (Rn << 5) | Rd; + return (size == 8 ? 0x9ac02800 : 0x1ac02800) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } -uint32_t lsrv(int Rd, int Rn, int Rm, unsigned size) +uint32_t lsrv(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x9ac02400 : 0x1ac02400) | (Rm << 16) | (Rn << 5) | Rd; + return (size == 8 ? 0x9ac02400 : 0x1ac02400) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } -uint32_t lsri(int Rd, int Rn, int shift, unsigned size) +uint32_t lsri(Register Rd, Register Rn, int shift, unsigned size) { return ubfm(Rd, Rn, shift, size == 8 ? 63 : 31, size); } -uint32_t asri(int Rd, int Rn, int shift, unsigned size) +uint32_t asri(Register Rd, Register Rn, int shift, unsigned size) { return sbfm(Rd, Rn, shift, size == 8 ? 63 : 31, size); } -uint32_t sxtb(int Rd, int Rn) +uint32_t sxtb(Register Rd, Register Rn) { return sbfm(Rd, Rn, 0, 7, 8); } -uint32_t sxth(int Rd, int Rn) +uint32_t sxth(Register Rd, Register Rn) { return sbfm(Rd, Rn, 0, 15, 8); } -uint32_t uxth(int Rd, int Rn) +uint32_t uxth(Register Rd, Register Rn) { return ubfm(Rd, Rn, 0, 15, 4); } -uint32_t sxtw(int Rd, int Rn) +uint32_t sxtw(Register Rd, Register Rn) { return sbfm(Rd, Rn, 0, 31, 8); } -uint32_t br(int Rn) +uint32_t br(Register Rn) { - return 0xd61f0000 | (Rn << 5); + return 0xd61f0000 | (Rn.index() << 5); } uint32_t fmovFdFn(int Fd, int Fn, unsigned size) @@ -99,80 +109,80 @@ uint32_t fmovFdFn(int Fd, int Fn, unsigned size) return (size == 8 ? 0x1e604000 : 0x1e204000) | (Fn << 5) | Fd; } -uint32_t fmovRdFn(int Rd, int Fn, unsigned size) +uint32_t fmovRdFn(Register Rd, int Fn, unsigned size) { - return (size == 8 ? 0x9e660000 : 0x1e260000) | (Fn << 5) | Rd; + return (size == 8 ? 0x9e660000 : 0x1e260000) | (Fn << 5) | Rd.index(); } -uint32_t fmovFdRn(int Fd, int Rn, unsigned size) +uint32_t fmovFdRn(int Fd, Register Rn, unsigned size) { - return (size == 8 ? 0x9e670000 : 0x1e270000) | (Rn << 5) | Fd; + return (size == 8 ? 0x9e670000 : 0x1e270000) | (Rn.index() << 5) | Fd; } -uint32_t orr(int Rd, int Rn, int Rm, unsigned size) +uint32_t orr(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0xaa0003e0 : 0x2a0003e0) | (Rm << 16) | (Rn << 5) | Rd; + return (size == 8 ? 0xaa0003e0 : 0x2a0003e0) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } -uint32_t mov(int Rd, int Rn, unsigned size) +uint32_t mov(Register Rd, Register Rn, unsigned size) { - return orr(Rd, 31, Rn, size); + return orr(Rd, Register(31), Rn, size); } -uint32_t movz(int Rd, int value, unsigned shift, unsigned size) +uint32_t movz(Register Rd, int value, unsigned shift, unsigned size) { return (size == 8 ? 0xd2800000 : 0x52800000) | ((shift >> 4) << 21) - | (value << 5) | Rd; + | (value << 5) | Rd.index(); } -uint32_t movn(int Rd, int value, unsigned shift, unsigned size) +uint32_t movn(Register Rd, int value, unsigned shift, unsigned size) { return (size == 8 ? 0x92800000 : 0x12800000) | ((shift >> 4) << 21) - | (value << 5) | Rd; + | (value << 5) | Rd.index(); } -uint32_t movk(int Rd, int value, unsigned shift, unsigned size) +uint32_t movk(Register Rd, int value, unsigned shift, unsigned size) { return (size == 8 ? 0xf2800000 : 0x72800000) | ((shift >> 4) << 21) - | (value << 5) | Rd; + | (value << 5) | Rd.index(); } -uint32_t ldrPCRel(int Rd, int offset, unsigned size) +uint32_t ldrPCRel(Register Rd, int offset, unsigned size) { - return (size == 8 ? 0x58000000 : 0x18000000) | (offset << 5) | Rd; + return (size == 8 ? 0x58000000 : 0x18000000) | (offset << 5) | Rd.index(); } -uint32_t add(int Rd, int Rn, int Rm, unsigned size) +uint32_t add(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x8b000000 : 0x0b000000) | (Rm << 16) | (Rn << 5) | Rd; + return (size == 8 ? 0x8b000000 : 0x0b000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } -uint32_t sub(int Rd, int Rn, int Rm, unsigned size) +uint32_t sub(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm << 16) | (Rn << 5) | Rd; + return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } -uint32_t madd(int Rd, int Rn, int Rm, int Ra, unsigned size) +uint32_t madd(Register Rd, Register Rn, Register Rm, Register Ra, unsigned size) { return (size == 8 ? 0x9b000000 : 0x1b000000) - | (Rm << 16) | (Ra << 10) | (Rn << 5) | Rd; + | (Rm.index() << 16) | (Ra.index() << 10) | (Rn.index() << 5) | Rd.index(); } -uint32_t mul(int Rd, int Rn, int Rm, unsigned size) +uint32_t mul(Register Rd, Register Rn, Register Rm, unsigned size) { - return madd(Rd, Rn, Rm, 31, size); + return madd(Rd, Rn, Rm, Register(31), size); } -uint32_t addi(int Rd, int Rn, int value, int shift, unsigned size) +uint32_t addi(Register Rd, Register Rn, int value, int shift, unsigned size) { return (size == 8 ? 0x91000000 : 0x11000000) | (shift ? 0x400000 : 0) - | (value << 10) | (Rn << 5) | Rd; + | (value << 10) | (Rn.index() << 5) | Rd.index(); } -uint32_t subi(int Rd, int Rn, int value, int shift, unsigned size) +uint32_t subi(Register Rd, Register Rn, int value, int shift, unsigned size) { return (size == 8 ? 0xd1000000 : 0x51000000) | (shift ? 0x400000 : 0) - | (value << 10) | (Rn << 5) | Rd; + | (value << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t fabs(int Fd, int Fn, unsigned size) @@ -195,22 +205,16 @@ uint32_t fcvtDdSn(int Fd, int Fn) return 0x1e22c000 | (Fn << 5) | Fd; } -uint32_t fcvtasXdDn(int Rd, int Fn) +uint32_t fcvtasXdDn(Register Rd, int Fn) { - return 0x9e640000 | (Fn << 5) | Rd; + return 0x9e640000 | (Fn << 5) | Rd.index(); } -uint32_t fcvtasWdSn(int Rd, int Fn) +uint32_t fcvtasWdSn(Register Rd, int Fn) { - return 0x1e240000 | (Fn << 5) | Rd; + return 0x1e240000 | (Fn << 5) | Rd.index(); } -} // namespace - -namespace avian { -namespace codegen { -namespace arm { - using namespace avian::util; void shiftLeftR(Context* c, @@ -308,9 +312,9 @@ void moveRR(Context* c, if (srcIsFpr and dstIsFpr) { append(c, fmovFdFn(fpr(dst), fpr(src), srcSize)); } else if (srcIsFpr) { - append(c, fmovRdFn(fpr(dst), fpr(src), srcSize)); + append(c, fmovRdFn(dst->low, fpr(src), srcSize)); } else { - append(c, fmovFdRn(fpr(dst), fpr(src), srcSize)); + append(c, fmovFdRn(fpr(dst), src->low, srcSize)); } } else { switch (srcSize) { @@ -365,7 +369,7 @@ void moveCR2(Context* c, if (isFpr(dst)) { // todo: could use a single fmov here and avoid the temporary for // constants that fit - lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); moveCR(c, size, src, size, &tmp); moveRR(c, size, &tmp, size, dst); c->client->releaseTemporary(tmp.low); diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index da2d7151fd..33784dbb1b 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -33,15 +33,6 @@ const int N_FPRS = 32; const RegisterMask GPR_MASK = 0xffffffff; const RegisterMask FPR_MASK = 0xffffffff00000000; -inline int fpr(int reg) -{ - return reg - N_GPRS; -} - -inline int fpr(lir::RegisterPair* reg) -{ - return fpr(reg->low); -} #else constexpr Register ThreadRegister(8); constexpr Register StackRegister(13); From b519e245e24474e8ffb9105352320c5ba2535047 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 22 Dec 2014 12:57:18 -0700 Subject: [PATCH 40/70] finish implementing operations64.cpp for ARM64 support This is totally untested so far. --- src/codegen/target/arm/operations64.cpp | 426 ++++++++++++++++++++---- src/codegen/target/arm/registers.h | 5 +- 2 files changed, 360 insertions(+), 71 deletions(-) diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 724f856d13..c3058102df 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -16,16 +16,17 @@ #if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 -namespace avian { -namespace codegen { -namespace arm { +namespace { -inline int fpr(Register reg) +using namespace avian::codegen; +using namespace avian::codegen::arm; + +Register fpr(Register reg) { - return reg.index() - N_GPRS; + return Register(reg.index() - N_GPRS); } -inline int fpr(lir::RegisterPair* reg) +Register fpr(lir::RegisterPair* reg) { return fpr(reg->low); } @@ -104,19 +105,19 @@ uint32_t br(Register Rn) return 0xd61f0000 | (Rn.index() << 5); } -uint32_t fmovFdFn(int Fd, int Fn, unsigned size) +uint32_t fmovFdFn(Register Fd, Register Fn, unsigned size) { - return (size == 8 ? 0x1e604000 : 0x1e204000) | (Fn << 5) | Fd; + return (size == 8 ? 0x1e604000 : 0x1e204000) | (Fn.index() << 5) | Fd.index(); } -uint32_t fmovRdFn(Register Rd, int Fn, unsigned size) +uint32_t fmovRdFn(Register Rd, Register Fn, unsigned size) { - return (size == 8 ? 0x9e660000 : 0x1e260000) | (Fn << 5) | Rd.index(); + return (size == 8 ? 0x9e660000 : 0x1e260000) | (Fn.index() << 5) | Rd.index(); } -uint32_t fmovFdRn(int Fd, Register Rn, unsigned size) +uint32_t fmovFdRn(Register Fd, Register Rn, unsigned size) { - return (size == 8 ? 0x9e670000 : 0x1e270000) | (Rn.index() << 5) | Fd; + return (size == 8 ? 0x9e670000 : 0x1e270000) | (Rn.index() << 5) | Fd.index(); } uint32_t orr(Register Rd, Register Rn, Register Rm, unsigned size) @@ -162,6 +163,18 @@ uint32_t sub(Register Rd, Register Rn, Register Rm, unsigned size) return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } +uint32_t and_(Register Rd, Register Rn, Register Rm, unsigned size) +{ + return (size == 8 ? 0x8a000000 : 0x0a000000) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); +} + +uint32_t eor(Register Rd, Register Rn, Register Rm, unsigned size) +{ + return (size == 8 ? 0xca000000 : 0x4a000000) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); +} + uint32_t madd(Register Rd, Register Rn, Register Rm, Register Ra, unsigned size) { return (size == 8 ? 0x9b000000 : 0x1b000000) @@ -185,36 +198,288 @@ uint32_t subi(Register Rd, Register Rn, int value, int shift, unsigned size) | (value << 10) | (Rn.index() << 5) | Rd.index(); } -uint32_t fabs(int Fd, int Fn, unsigned size) +uint32_t fabs_(Register Fd, Register Fn, unsigned size) { - return (size == 8 ? 0x1e60c000 : 0x1e20c000) | (Fn << 5) | Fd; + return (size == 8 ? 0x1e60c000 : 0x1e20c000) | (Fn.index() << 5) | Fd.index(); } -uint32_t fneg(int Fd, int Fn, unsigned size) +uint32_t fneg(Register Fd, Register Fn, unsigned size) { - return (size == 8 ? 0x1e614000 : 0x1e214000) | (Fn << 5) | Fd; + return (size == 8 ? 0x1e614000 : 0x1e214000) | (Fn.index() << 5) | Fd.index(); } -uint32_t fcvtSdDn(int Fd, int Fn) +uint32_t fsqrt(Register Fd, Register Fn, unsigned size) { - return 0x1e624000 | (Fn << 5) | Fd; + return (size == 8 ? 0x1e61c000 : 0x1e21c000) | (Fn.index() << 5) | Fd.index(); } -uint32_t fcvtDdSn(int Fd, int Fn) +uint32_t fadd(Register Fd, Register Fn, Register Fm, unsigned size) { - return 0x1e22c000 | (Fn << 5) | Fd; + return (size == 8 ? 0x1e602800 : 0x1e202800) | (Fm.index() << 16) + | (Fn.index() << 5) | Fd.index(); } -uint32_t fcvtasXdDn(Register Rd, int Fn) +uint32_t fsub(Register Fd, Register Fn, Register Fm, unsigned size) { - return 0x9e640000 | (Fn << 5) | Rd.index(); + return (size == 8 ? 0x1e603800 : 0x1e203800) | (Fm.index() << 16) + | (Fn.index() << 5) | Fd.index(); } -uint32_t fcvtasWdSn(Register Rd, int Fn) +uint32_t fmul(Register Fd, Register Fn, Register Fm, unsigned size) { - return 0x1e240000 | (Fn << 5) | Rd.index(); + return (size == 8 ? 0x1e600800 : 0x1e200800) | (Fm.index() << 16) + | (Fn.index() << 5) | Fd.index(); } +uint32_t fdiv(Register Fd, Register Fn, Register Fm, unsigned size) +{ + return (size == 8 ? 0x1e601800 : 0x1e201800) | (Fm.index() << 16) + | (Fn.index() << 5) | Fd.index(); +} + +uint32_t fcvtSdDn(Register Fd, Register Fn) +{ + return 0x1e624000 | (Fn.index() << 5) | Fd.index(); +} + +uint32_t fcvtDdSn(Register Fd, Register Fn) +{ + return 0x1e22c000 | (Fn.index() << 5) | Fd.index(); +} + +uint32_t fcvtasXdDn(Register Rd, Register Fn) +{ + return 0x9e640000 | (Fn.index() << 5) | Rd.index(); +} + +uint32_t fcvtasWdSn(Register Rd, Register Fn) +{ + return 0x1e240000 | (Fn.index() << 5) | Rd.index(); +} + +uint32_t scvtfDdWn(Register Fd, Register Rn) +{ + return 0x1e620000 | (Rn.index() << 5) | Fd.index(); +} + +uint32_t scvtfSdWn(Register Fd, Register Rn) +{ + return 0x1e220000 | (Rn.index() << 5) | Fd.index(); +} + +uint32_t strFs(Register Fs, Register Rn, Register Rm, unsigned size) +{ + return (size == 8 ? 0xfc206800 : 0xbc206800) | (Rm.index() << 16) + | (Rn.index() << 5) | Fs.index(); +} + +uint32_t strb(Register Rs, Register Rn, Register Rm) +{ + return 0x38206800 | (Rm.index() << 16) | (Rn.index() << 5) | Rs.index(); +} + +uint32_t strh(Register Rs, Register Rn, Register Rm) +{ + return 0x78206800 | (Rm.index() << 16) | (Rn.index() << 5) | Rs.index(); +} + +uint32_t striFs(Register Fs, Register Rn, int offset, unsigned size) +{ + return (size == 8 ? 0xfc000000 : 0xbc000000) | (offset << 16) + | (Rn.index() << 5) | Fs.index(); +} + +uint32_t str(Register Rs, Register Rn, Register Rm, unsigned size) +{ + return (size == 8 ? 0xf8206800 : 0xb8206800) | (Rm.index() << 16) + | (Rn.index() << 5) | Rs.index(); +} + +uint32_t strbi(Register Rs, Register Rn, int offset) +{ + return 0x39000000 | (offset << 10) | (Rn.index() << 5) | Rs.index(); +} + +uint32_t strhi(Register Rs, Register Rn, int offset) +{ + return 0x79000000 | (offset << 10) | (Rn.index() << 5) | Rs.index(); +} + +uint32_t stri(Register Rs, Register Rn, int offset, unsigned size) +{ + return (size == 8 ? 0xb9000000 : 0xf9000000) | (offset << 10) + | (Rn.index() << 5) | Rs.index(); +} + +uint32_t ldrFd(Register Fd, Register Rn, Register Rm, unsigned size) +{ + return (size == 8 ? 0xfc606800 : 0xbc606800) | (Rm.index() << 16) + | (Rn.index() << 5) | Fd.index(); +} + +uint32_t ldrb(Register Rd, Register Rn, Register Rm) +{ + return 0x38606800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrsb(Register Rd, Register Rn, Register Rm) +{ + return 0x38e06800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrh(Register Rd, Register Rn, Register Rm) +{ + return 0x78606800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrsh(Register Rd, Register Rn, Register Rm) +{ + return 0x78e06800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrsw(Register Rd, Register Rn, Register Rm) +{ + return 0xb8a06800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldr(Register Rd, Register Rn, Register Rm, unsigned size) +{ + return (size == 8 ? 0xf8606800 : 0xb8606800) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldriFd(Register Fd, Register Rn, int offset, unsigned size) +{ + return (size == 8 ? 0xfc400000 : 0xbc400000) | (offset << 16) + | (Rn.index() << 5) | Fd.index(); +} + +uint32_t ldrbi(Register Rd, Register Rn, int offset) +{ + return 0x39400000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrsbi(Register Rd, Register Rn, int offset) +{ + return 0x39c00000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrhi(Register Rd, Register Rn, int offset) +{ + return 0x79400000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrshi(Register Rd, Register Rn, int offset) +{ + return 0x79c00000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldrswi(Register Rd, Register Rn, int offset) +{ + return 0xb9800000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); +} + +uint32_t ldri(Register Rd, Register Rn, int offset, unsigned size) +{ + return (size == 8 ? 0xb9400000 : 0xf9400000) | (offset << 10) + | (Rn.index() << 5) | Rd.index(); +} + +uint32_t fcmp(Register Fn, Register Fm, unsigned size) +{ + return (size == 8 ? 0x1e602000 : 0x1e202000) | (Fm.index() << 16) + | (Fn.index() << 5); +} + +uint32_t neg(Register Rd, Register Rm, unsigned size) +{ + return (size == 8 ? 0xcb0003e0 : 0x4b0003e0) | (Rm.index() << 16) + | Rd.index(); +} + +uint32_t cmp(Register Rn, Register Rm, unsigned size) +{ + return (size == 8 ? 0xeb00001f : 0x6b00001f) | (Rm.index() << 16) + | (Rn.index() << 5); +} + +uint32_t cmpi(Register Rn, int value, unsigned shift, unsigned size) +{ + return (size == 8 ? 0xf100001f : 0x7100001f) | (shift == 12 ? 0x400000 : 0) + | (value << 10) | (Rn.index() << 5); +} + +uint32_t b(int offset) +{ + return 0x14000000 | (offset >> 2); +} + +uint32_t bl(int offset) +{ + return 0x94000000 | (offset >> 2); +} + +uint32_t blr(Register Rn) +{ + return 0xd63f0000 | (Rn.index() << 5); +} + +uint32_t beq(int offset) +{ + return 0x54000000 | (offset >> 2); +} + +uint32_t bne(int offset) +{ + return 0x54000001 | (offset >> 2); +} + +uint32_t blt(int offset) +{ + return 0x5400000b | (offset >> 2); +} + +uint32_t bgt(int offset) +{ + return 0x5400000c | (offset >> 2); +} + +uint32_t ble(int offset) +{ + return 0x5400000d | (offset >> 2); +} + +uint32_t bge(int offset) +{ + return 0x5400000a | (offset >> 2); +} + +uint32_t bhi(int offset) +{ + return 0x54000008 | (offset >> 2); +} + +uint32_t bpl(int offset) +{ + return 0x54000005 | (offset >> 2); +} + +uint32_t brk(int flag) +{ + return 0xd4200020 | (flag << 5); +} + +uint32_t dmb(int flag) +{ + return 0xd50330bf | (flag << 8); +} + +} // namespace + +namespace avian { +namespace codegen { +namespace arm { + using namespace avian::util; void shiftLeftR(Context* c, @@ -533,9 +798,9 @@ void int2FloatRR(Context* c, lir::RegisterPair* b) { if (size == 8) { - append(c, scvtfDdWn(fpr(b), b->low)); + append(c, scvtfDdWn(fpr(a), b->low)); } else { - append(c, scvtfSdWn(fpr(b), b->low)); + append(c, scvtfSdWn(fpr(a), b->low)); } } @@ -554,7 +819,7 @@ void floatAddR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, fadd(fpr, dst, fpr(b), fpr(a), size)); + append(c, fadd(fpr(dst), fpr(b), fpr(a), size)); } void floatSubtractR(Context* c, @@ -563,7 +828,7 @@ void floatSubtractR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, fsub(fpr, dst, fpr(b), fpr(a), size)); + append(c, fsub(fpr(dst), fpr(b), fpr(a), size)); } void floatMultiplyR(Context* c, @@ -572,7 +837,7 @@ void floatMultiplyR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, fmul(fpr, dst, fpr(b), fpr(a), size)); + append(c, fmul(fpr(dst), fpr(b), fpr(a), size)); } void floatDivideR(Context* c, @@ -581,19 +846,19 @@ void floatDivideR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, fdiv(fpr, dst, fpr(b), fpr(a), size)); + append(c, fdiv(fpr(dst), fpr(b), fpr(a), size)); } -int normalize(Context* c, - int offset, - int index, - unsigned scale, - bool* preserveIndex, - bool* release) +Register normalize(Context* c, + int offset, + Register index, + unsigned scale, + bool* preserveIndex, + bool* release) { if (offset != 0 or scale != 1) { - lir::Register normalizedIndex( - *preserveIndex ? con->client->acquireTemporary(GPR_MASK) : index); + lir::RegisterPair normalizedIndex( + *preserveIndex ? c->client->acquireTemporary(GPR_MASK) : index); if (*preserveIndex) { *release = true; @@ -602,10 +867,10 @@ int normalize(Context* c, *release = false; } - int scaled; + Register scaled; if (scale != 1) { - lir::Register unscaledIndex(index); + lir::RegisterPair unscaledIndex(index); ResolvedPromise scalePromise(log(scale)); lir::Constant scaleConstant(&scalePromise); @@ -622,12 +887,12 @@ int normalize(Context* c, } if (offset != 0) { - lir::Register untranslatedIndex(scaled); + lir::RegisterPair untranslatedIndex(scaled); ResolvedPromise offsetPromise(offset); lir::Constant offsetConstant(&offsetPromise); - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); moveCR(c, vm::TargetBytesPerWord, &offsetConstant, @@ -638,7 +903,7 @@ int normalize(Context* c, &tmp, &untranslatedIndex, &normalizedIndex); - con->client->releaseTemporary(tmp.low); + c->client->releaseTemporary(tmp.low); } return normalizedIndex.low; @@ -651,15 +916,21 @@ int normalize(Context* c, void store(Context* c, unsigned size, lir::RegisterPair* src, - int base, + Register base, int offset, - int index, + Register index, unsigned scale, bool preserveIndex) { - if (index != lir::NoRegister) { + if (index != NoRegister) { bool release; - int normalized + + // todo: browsing the instruction set, it looks like we could do a + // scaled store or load in a single instruction if the offset is + // zero, and we could simplify things for the case of non-zero + // offsets also + + Register normalized = normalize(c, offset, index, scale, &preserveIndex, &release); if (isFpr(src)) { @@ -726,7 +997,7 @@ void store(Context* c, } } } else { - lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); ResolvedPromise offsetPromise(offset); lir::Constant offsetConstant(&offsetPromise); moveCR(c, @@ -755,18 +1026,18 @@ void moveRM(Context* c, void load(Context* c, unsigned srcSize, - int base, + Register base, int offset, - int index, + Register index, unsigned scale, unsigned dstSize, lir::RegisterPair* dst, bool preserveIndex, bool signExtend) { - if (index != lir::NoRegister) { + if (index != NoRegister) { bool release; - int normalized + Register normalized = normalize(c, offset, index, scale, &preserveIndex, &release); if (isFpr(dst)) { // FPR load @@ -819,7 +1090,7 @@ void load(Context* c, switch (srcSize) { case 4: case 8: - append(c, ldriFd(fpr(dst->low), base, offset)); + append(c, ldriFd(fpr(dst->low), base, offset, srcSize)); break; default: @@ -848,7 +1119,7 @@ void load(Context* c, if (signExtend and srcSize == 4 and dstSize == 8) { append(c, ldrswi(dst->low, base, offset)); } else { - append(c, ldri(dst->low, base, offset, size)); + append(c, ldri(dst->low, base, offset, srcSize)); } break; @@ -857,7 +1128,7 @@ void load(Context* c, } } } else { - lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); ResolvedPromise offsetPromise(offset); lir::Constant offsetConstant(&offsetPromise); moveCR(c, @@ -927,7 +1198,7 @@ void andC(Context* c, if (~v) { bool useTemporary = b->low == dst->low; - lir::Register tmp(dst->low); + lir::RegisterPair tmp(dst->low); if (useTemporary) { tmp.low = c->client->acquireTemporary(GPR_MASK); } @@ -972,7 +1243,7 @@ void moveAR(Context* c, lir::Constant constant(src->address); moveCR(c, srcSize, &constant, dstSize, dst); - lir::Memory memory(dst->low, 0, -1, 0); + lir::Memory memory(dst->low, 0, NoRegister, 0); moveMR(c, dstSize, &memory, dstSize, dst); } @@ -995,7 +1266,7 @@ void compareRR(Context* c, void compareCR(Context* c, unsigned aSize, lir::Constant* a, - unsigned bSize, + unsigned bSize UNUSED, lir::RegisterPair* b) { assertT(c, aSize == bSize); @@ -1003,9 +1274,9 @@ void compareCR(Context* c, int32_t v = a->value->value(); if (v) { if (v > 0 and v < 0x1000) { - append(c, cmpi(b->low, v, 0, size)); + append(c, cmpi(b->low, v, 0, aSize)); } else if (v > 0 and v < 0x1000000 and v % 0x1000 == 0) { - append(c, cmpi(b->low, v >> 12, 12, size)); + append(c, cmpi(b->low, v >> 12, 12, aSize)); } else { // todo abort(c); @@ -1021,7 +1292,7 @@ void compareCM(Context* c, { assertT(c, aSize == bSize); - lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); moveMR(c, bSize, b, bSize, &tmp); compareCR(c, aSize, a, bSize, &tmp); c->client->releaseTemporary(tmp.low); @@ -1035,7 +1306,7 @@ void compareRM(Context* c, { assertT(c, aSize == bSize); - lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); moveMR(c, bSize, b, bSize, &tmp); compareRR(c, aSize, a, bSize, &tmp); c->client->releaseTemporary(tmp.low); @@ -1083,7 +1354,7 @@ int32_t branch(Context* c, lir::TernaryOperation op) void conditional(Context* c, int32_t branch, lir::Constant* target) { - appendOffsetTask(c, target->value, offsetPromise(con)); + appendOffsetTask(c, target->value, offsetPromise(c)); append(c, branch); } @@ -1149,7 +1420,7 @@ ShiftMaskPromise* shiftMaskPromise(Context* c, unsigned shift, int64_t mask) { - return new (con->zone) ShiftMaskPromise(base, shift, mask); + return new (c->zone) ShiftMaskPromise(base, shift, mask); } void moveCM(Context* c, @@ -1170,10 +1441,10 @@ void moveCM(Context* c, } break; default: - lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); moveCR(c, srcSize, src, dstSize, &tmp); moveRM(c, dstSize, &tmp, dstSize, dst); - con->client->releaseTemporary(tmp.low); + c->client->releaseTemporary(tmp.low); } } @@ -1206,7 +1477,8 @@ void longCallC(Context* c, unsigned size UNUSED, lir::Constant* target) { assertT(c, size == vm::TargetBytesPerWord); - lir::Register tmp(9); // a non-arg reg that we don't mind clobbering + lir::RegisterPair tmp( + Register(9)); // a non-arg reg that we don't mind clobbering moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c)); callR(c, vm::TargetBytesPerWord, &tmp); } @@ -1215,7 +1487,8 @@ void longJumpC(Context* c, unsigned size UNUSED, lir::Constant* target) { assertT(c, size == vm::TargetBytesPerWord); - lir::Register tmp(9); // a non-arg reg that we don't mind clobbering + lir::RegisterPair tmp( + Register(9)); // a non-arg reg that we don't mind clobbering moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c)); jumpR(c, vm::TargetBytesPerWord, &tmp); } @@ -1246,7 +1519,7 @@ void trap(Context* c) void memoryBarrier(Context* c) { - append(c, dmb()); + append(c, dmb(0xF)); } void loadBarrier(Context* c) @@ -1264,6 +1537,21 @@ void storeLoadBarrier(Context* c) memoryBarrier(c); } +bool needJump(MyBlock*) +{ + return false; +} + +unsigned padding(MyBlock*, unsigned) +{ + return 0; +} + +void resolve(MyBlock*) +{ + // ignore +} + } // namespace arm } // namespace codegen } // namespace avian diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index 33784dbb1b..18622a81e5 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -14,6 +14,8 @@ #include #include +#include "avian/environment.h" + namespace avian { namespace codegen { namespace arm { @@ -21,11 +23,10 @@ namespace arm { const uint64_t MASK_LO32 = 0xffffffff; const unsigned MASK_LO8 = 0xff; -#ifdef ARCH_arm64 +#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 constexpr Register ThreadRegister(19); constexpr Register StackRegister(31); constexpr Register LinkRegister(30); -constexpr Register LinkRegister(29); constexpr Register ProgramCounter(0xFE); // i.e. unaddressable const int N_GPRS = 32; From 9158ee39c00c35f42090f75cc496ef97391fd5ba Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 23 Dec 2014 16:57:40 -0700 Subject: [PATCH 41/70] remove 64-bit code from compile-arm.S since it's moved to compile-arm64.S --- src/compile-arm.S | 104 ---------------------------------------------- 1 file changed, 104 deletions(-) diff --git a/src/compile-arm.S b/src/compile-arm.S index 432b79e646..2f566f9558 100644 --- a/src/compile-arm.S +++ b/src/compile-arm.S @@ -23,108 +23,6 @@ # define GLOBAL(x) x #endif -#ifdef __aarch64__ - -.globl GLOBAL(vmInvoke) -.align 2 -GLOBAL(vmInvoke): - // arguments: - // x0 : thread - // x1 : function - // x2 : arguments - // w3 : argumentFootprint - // w4 : frameSize (not used) - // w5 : returnType - - // allocate frame - stp x29, x30, [sp,#-96]! - - // save callee-saved register values - stp x19, x20, [sp,#16] - stp x21, x22, [sp,#32] - stp x23, x24, [sp,#48] - stp x25, x26, [sp,#64] - stp x27, x28, [sp,#80] - - // save return type - str w5, [sp,#-16]! - - mov x5, sp - str x5, [x0,#TARGET_THREAD_SCRATCH] - - // copy arguments into place - sub sp, sp, w3 - mov x5, #0 - b LOCAL(vmInvoke_argumentTest) - -LOCAL(vmInvoke_argumentLoop): - ldr x5, [x2, x4] - str x5, [sp, x4] - add x4, x4, #BYTES_PER_WORD - -LOCAL(vmInvoke_argumentTest): - cmp x4, x3 - blt LOCAL(vmInvoke_argumentLoop) - - // we use x19 to hold the thread pointer, by convention - mov x19, x0 - - // load and call function address - blr x1 - -.globl GLOBAL(vmInvoke_returnAddress) -.align 2 -GLOBAL(vmInvoke_returnAddress): - // restore stack pointer - ldr x5, [x19, #TARGET_THREAD_SCRATCH] - mov sp, x5 - - // clear MyThread::stack to avoid confusing another thread calling - // java.lang.Thread.getStackTrace on this one. See - // MyProcess::getStackTrace in compile.cpp for details on how we get - // a reliable stack trace from a thread that might be interrupted at - // any point in its execution. - mov x5, #0 - str x5, [x19, #TARGET_THREAD_STACK] - -.globl GLOBAL(vmInvoke_safeStack) -.align 2 -GLOBAL(vmInvoke_safeStack): - -#ifdef AVIAN_CONTINUATIONS -#error todo -#endif // AVIAN_CONTINUATIONS - - mov x5, #0 - str x5, [x19, #TARGET_THREAD_STACK] - - // restore return type - ldr w5, [sp], #4 - - // restore callee-saved register values - ldp x19, x20, [sp,#16] - ldp x21, x22, [sp,#32] - ldp x23, x24, [sp,#48] - ldp x25, x26, [sp,#64] - ldp x27, x28, [sp,#80] - ldp x29, x30, [sp],#96 - -LOCAL(vmInvoke_return): - br x30 - -.globl GLOBAL(vmJumpAndInvoke) -.align 2 -GLOBAL(vmJumpAndInvoke): -#ifdef AVIAN_CONTINUATIONS -#error todo -#else // not AVIAN_CONTINUATIONS - // vmJumpAndInvoke should only be called when continuations are - // enabled, so we force a crash if we reach here: - brk 0 -#endif // not AVIAN_CONTINUATIONS - -#elif defined __arm__ - #define CONTINUATION_NEXT 4 #define CONTINUATION_ADDRESS 16 #define CONTINUATION_RETURN_ADDRESS_OFFSET 20 @@ -355,5 +253,3 @@ LOCAL(vmJumpAndInvoke_getAddress_word): mov r1,#0 ldr r1,[r1] #endif // not AVIAN_CONTINUATIONS - -#endif // __arm__ From cbea966d1dceede318c814563ef38578c3f5a5fe Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 23 Dec 2014 16:59:04 -0700 Subject: [PATCH 42/70] various ARM64 JIT bugfixes Three of the tests now pass. Yay! --- src/codegen/target/arm/assembler.cpp | 11 ++- src/codegen/target/arm/fixup.cpp | 122 ++++++++++++++++++++++-- src/codegen/target/arm/fixup.h | 4 + src/codegen/target/arm/operations32.cpp | 95 ------------------ src/codegen/target/arm/operations64.cpp | 116 +++++++++++++--------- src/compile-arm64.S | 16 ++-- 6 files changed, 209 insertions(+), 155 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 23b07ef201..b4046223e1 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -946,11 +946,20 @@ class MyAssembler : public Assembler { unsigned instruction = o->block->start + padding(o->block, o->offset) + o->offset; + int32_t* p = reinterpret_cast(dst + instruction); + +#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 + int32_t v = entry - instruction; + expect(&con, v == (v & PoolOffsetMask)); + + const int32_t mask = (PoolOffsetMask >> 2) << 5; + *p = (((v >> 2) << 5) & mask) | ((~mask) & *p); +#else int32_t v = (entry - 8) - instruction; expect(&con, v == (v & PoolOffsetMask)); - int32_t* p = reinterpret_cast(dst + instruction); *p = (v & PoolOffsetMask) | ((~PoolOffsetMask) & *p); +#endif poolSize += TargetBytesPerWord; } diff --git a/src/codegen/target/arm/fixup.cpp b/src/codegen/target/arm/fixup.cpp index e1d41b6eb4..7f5c0ff277 100644 --- a/src/codegen/target/arm/fixup.cpp +++ b/src/codegen/target/arm/fixup.cpp @@ -92,14 +92,27 @@ bool bounded(int right, int left, int32_t v) void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value) { - // ARM's PC is two words ahead, and branches drop the bottom 2 bits. - int32_t v = (reinterpret_cast(value) - (instruction + 8)) >> 2; - - int32_t mask; - expect(s, bounded(0, 8, v)); - mask = 0xFFFFFF; - int32_t* p = reinterpret_cast(instruction); + +#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 + int32_t v; + int32_t mask; + if ((*p >> 24) == 0x54) { + // conditional branch + v = ((reinterpret_cast(value) - instruction) >> 2) << 5; + mask = 0xFFFFE0; + } else { + // unconditional branch + v = (reinterpret_cast(value) - instruction) >> 2; + mask = 0x3FFFFFF; + } +#else + int32_t v = (reinterpret_cast(value) - (instruction + 8)) >> 2; + const int32_t mask = 0xFFFFFF; +#endif + + expect(s, bounded(0, 8, v)); + *p = (v & mask) | ((~mask) & *p); return instruction + 4; @@ -214,6 +227,101 @@ void appendPoolEvent(Context* con, b->poolEventTail = e; } +bool needJump(MyBlock* b) +{ + return b->next or b->size != (b->size & PoolOffsetMask); +} + +unsigned padding(MyBlock* b, unsigned offset) +{ + unsigned total = 0; + for (PoolEvent* e = b->poolEventHead; e; e = e->next) { + if (e->offset <= offset) { + if (needJump(b)) { + total += vm::TargetBytesPerWord; + } + for (PoolOffset* o = e->poolOffsetHead; o; o = o->next) { + total += vm::TargetBytesPerWord; + } + } else { + break; + } + } + return total; +} + +void resolve(MyBlock* b) +{ + Context* con = b->context; + + if (b->poolOffsetHead) { + if (con->poolOffsetTail) { + con->poolOffsetTail->next = b->poolOffsetHead; + } else { + con->poolOffsetHead = b->poolOffsetHead; + } + con->poolOffsetTail = b->poolOffsetTail; + } + + if (con->poolOffsetHead) { + bool append; + if (b->next == 0 or b->next->poolEventHead) { + append = true; + } else { + int32_t v + = (b->start + b->size + b->next->size + vm::TargetBytesPerWord - 8) + - (con->poolOffsetHead->offset + con->poolOffsetHead->block->start); + + append = (v != (v & PoolOffsetMask)); + + if (DebugPool) { + fprintf(stderr, + "current %p %d %d next %p %d %d\n", + b, + b->start, + b->size, + b->next, + b->start + b->size, + b->next->size); + fprintf(stderr, + "offset %p %d is of distance %d to next block; append? %d\n", + con->poolOffsetHead, + con->poolOffsetHead->offset, + v, + append); + } + } + + if (append) { +#ifndef NDEBUG + int32_t v + = (b->start + b->size - 8) + - (con->poolOffsetHead->offset + con->poolOffsetHead->block->start); + + expect(con, v == (v & PoolOffsetMask)); +#endif // not NDEBUG + + appendPoolEvent( + con, b, b->size, con->poolOffsetHead, con->poolOffsetTail); + + if (DebugPool) { + for (PoolOffset* o = con->poolOffsetHead; o; o = o->next) { + fprintf(stderr, + "include %p %d in pool event %p at offset %d in block %p\n", + o, + o->offset, + b->poolEventTail, + b->size, + b); + } + } + + con->poolOffsetHead = 0; + con->poolOffsetTail = 0; + } + } +} + } // namespace arm } // namespace codegen } // namespace avian diff --git a/src/codegen/target/arm/fixup.h b/src/codegen/target/arm/fixup.h index 5460295d95..2e9c0aca01 100644 --- a/src/codegen/target/arm/fixup.h +++ b/src/codegen/target/arm/fixup.h @@ -27,7 +27,11 @@ namespace arm { const bool DebugPool = false; +#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 +const int32_t PoolOffsetMask = 0x1FFFFF; +#else const int32_t PoolOffsetMask = 0xFFF; +#endif class Task { public: diff --git a/src/codegen/target/arm/operations32.cpp b/src/codegen/target/arm/operations32.cpp index 5a9f5e8a0e..07dd7f0175 100644 --- a/src/codegen/target/arm/operations32.cpp +++ b/src/codegen/target/arm/operations32.cpp @@ -181,101 +181,6 @@ void unsignedShiftRightC(Context* con, } } -bool needJump(MyBlock* b) -{ - return b->next or b->size != (b->size & PoolOffsetMask); -} - -unsigned padding(MyBlock* b, unsigned offset) -{ - unsigned total = 0; - for (PoolEvent* e = b->poolEventHead; e; e = e->next) { - if (e->offset <= offset) { - if (needJump(b)) { - total += vm::TargetBytesPerWord; - } - for (PoolOffset* o = e->poolOffsetHead; o; o = o->next) { - total += vm::TargetBytesPerWord; - } - } else { - break; - } - } - return total; -} - -void resolve(MyBlock* b) -{ - Context* con = b->context; - - if (b->poolOffsetHead) { - if (con->poolOffsetTail) { - con->poolOffsetTail->next = b->poolOffsetHead; - } else { - con->poolOffsetHead = b->poolOffsetHead; - } - con->poolOffsetTail = b->poolOffsetTail; - } - - if (con->poolOffsetHead) { - bool append; - if (b->next == 0 or b->next->poolEventHead) { - append = true; - } else { - int32_t v - = (b->start + b->size + b->next->size + vm::TargetBytesPerWord - 8) - - (con->poolOffsetHead->offset + con->poolOffsetHead->block->start); - - append = (v != (v & PoolOffsetMask)); - - if (DebugPool) { - fprintf(stderr, - "current %p %d %d next %p %d %d\n", - b, - b->start, - b->size, - b->next, - b->start + b->size, - b->next->size); - fprintf(stderr, - "offset %p %d is of distance %d to next block; append? %d\n", - con->poolOffsetHead, - con->poolOffsetHead->offset, - v, - append); - } - } - - if (append) { -#ifndef NDEBUG - int32_t v - = (b->start + b->size - 8) - - (con->poolOffsetHead->offset + con->poolOffsetHead->block->start); - - expect(con, v == (v & PoolOffsetMask)); -#endif // not NDEBUG - - appendPoolEvent( - con, b, b->size, con->poolOffsetHead, con->poolOffsetTail); - - if (DebugPool) { - for (PoolOffset* o = con->poolOffsetHead; o; o = o->next) { - fprintf(stderr, - "include %p %d in pool event %p at offset %d in block %p\n", - o, - o->offset, - b->poolEventTail, - b->size, - b); - } - } - - con->poolOffsetHead = 0; - con->poolOffsetTail = 0; - } - } -} - void jumpR(Context* con, unsigned size UNUSED, lir::RegisterPair* target) { assertT(con, size == vm::TargetBytesPerWord); diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index c3058102df..32a31cf2f5 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -125,9 +125,16 @@ uint32_t orr(Register Rd, Register Rn, Register Rm, unsigned size) return (size == 8 ? 0xaa0003e0 : 0x2a0003e0) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } +uint32_t addi(Register Rd, Register Rn, int value, int shift, unsigned size) +{ + return (size == 8 ? 0x91000000 : 0x11000000) | (shift ? 0x400000 : 0) + | (value << 10) | (Rn.index() << 5) | Rd.index(); +} + uint32_t mov(Register Rd, Register Rn, unsigned size) { - return orr(Rd, Register(31), Rn, size); + return Rn.index() == 31 ? addi(Rd, Rn, 0, 0, size) + : orr(Rd, Register(31), Rn, size); } uint32_t movz(Register Rd, int value, unsigned shift, unsigned size) @@ -150,7 +157,8 @@ uint32_t movk(Register Rd, int value, unsigned shift, unsigned size) uint32_t ldrPCRel(Register Rd, int offset, unsigned size) { - return (size == 8 ? 0x58000000 : 0x18000000) | (offset << 5) | Rd.index(); + return (size == 8 ? 0x58000000 : 0x18000000) | ((offset >> 2) << 5) + | Rd.index(); } uint32_t add(Register Rd, Register Rn, Register Rm, unsigned size) @@ -186,12 +194,6 @@ uint32_t mul(Register Rd, Register Rn, Register Rm, unsigned size) return madd(Rd, Rn, Rm, Register(31), size); } -uint32_t addi(Register Rd, Register Rn, int value, int shift, unsigned size) -{ - return (size == 8 ? 0x91000000 : 0x11000000) | (shift ? 0x400000 : 0) - | (value << 10) | (Rn.index() << 5) | Rd.index(); -} - uint32_t subi(Register Rd, Register Rn, int value, int shift, unsigned size) { return (size == 8 ? 0xd1000000 : 0x51000000) | (shift ? 0x400000 : 0) @@ -307,8 +309,8 @@ uint32_t strhi(Register Rs, Register Rn, int offset) uint32_t stri(Register Rs, Register Rn, int offset, unsigned size) { - return (size == 8 ? 0xb9000000 : 0xf9000000) | (offset << 10) - | (Rn.index() << 5) | Rs.index(); + return (size == 8 ? 0xf9000000 : 0xb9000000) + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Rs.index(); } uint32_t ldrFd(Register Fd, Register Rn, Register Rm, unsigned size) @@ -381,8 +383,8 @@ uint32_t ldrswi(Register Rd, Register Rn, int offset) uint32_t ldri(Register Rd, Register Rn, int offset, unsigned size) { - return (size == 8 ? 0xb9400000 : 0xf9400000) | (offset << 10) - | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0xf9400000 : 0xb9400000) + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t fcmp(Register Fn, Register Fm, unsigned size) @@ -400,7 +402,7 @@ uint32_t neg(Register Rd, Register Rm, unsigned size) uint32_t cmp(Register Rn, Register Rm, unsigned size) { return (size == 8 ? 0xeb00001f : 0x6b00001f) | (Rm.index() << 16) - | (Rn.index() << 5); + | (Rn.index() == 31 ? 0x2063ff : (Rn.index() << 5)); } uint32_t cmpi(Register Rn, int value, unsigned shift, unsigned size) @@ -426,42 +428,42 @@ uint32_t blr(Register Rn) uint32_t beq(int offset) { - return 0x54000000 | (offset >> 2); + return 0x54000000 | ((offset >> 2) << 5); } uint32_t bne(int offset) { - return 0x54000001 | (offset >> 2); + return 0x54000001 | ((offset >> 2) << 5); } uint32_t blt(int offset) { - return 0x5400000b | (offset >> 2); + return 0x5400000b | ((offset >> 2) << 5); } uint32_t bgt(int offset) { - return 0x5400000c | (offset >> 2); + return 0x5400000c | ((offset >> 2) << 5); } uint32_t ble(int offset) { - return 0x5400000d | (offset >> 2); + return 0x5400000d | ((offset >> 2) << 5); } uint32_t bge(int offset) { - return 0x5400000a | (offset >> 2); + return 0x5400000a | ((offset >> 2) << 5); } uint32_t bhi(int offset) { - return 0x54000008 | (offset >> 2); + return 0x54000008 | ((offset >> 2) << 5); } uint32_t bpl(int offset) { - return 0x54000005 | (offset >> 2); + return 0x54000005 | ((offset >> 2) << 5); } uint32_t brk(int flag) @@ -966,7 +968,7 @@ void store(Context* c, if (release) { c->client->releaseTemporary(normalized); } - } else if (abs(offset) == (abs(offset) & 0xFF)) { + } else if (abs(offset) == (abs(offset) & 0xFFF)) { if (isFpr(src)) { switch (size) { case 4: @@ -988,7 +990,12 @@ void store(Context* c, break; case 4: + assertT(c, offset == (offset & (~3))); + append(c, stri(src->low, base, offset, size)); + break; + case 8: + assertT(c, offset == (offset & (~7))); append(c, stri(src->low, base, offset, size)); break; @@ -1020,8 +1027,21 @@ void moveRM(Context* c, { assertT(c, srcSize == dstSize); - store( - c, srcSize, src, dst->base, dst->offset, dst->index, dst->scale, true); + if (src->low.index() == 31) { + assertT(c, c->client == 0); // the compiler should never ask us to + // store the SP; we'll only get here + // when assembling a thunk + + lir::RegisterPair tmp(Register(9)); // we're in a thunk, so we can + // clobber this + + moveRR(c, srcSize, src, srcSize, &tmp); + store( + c, srcSize, &tmp, dst->base, dst->offset, dst->index, dst->scale, true); + } else { + store( + c, srcSize, src, dst->base, dst->offset, dst->index, dst->scale, true); + } } void load(Context* c, @@ -1085,7 +1105,7 @@ void load(Context* c, if (release) { c->client->releaseTemporary(normalized); } - } else if (abs(offset) == (abs(offset) & 0xFF)) { + } else if (abs(offset) == (abs(offset) & 0xFFF)) { if (isFpr(dst)) { switch (srcSize) { case 4: @@ -1119,6 +1139,7 @@ void load(Context* c, if (signExtend and srcSize == 4 and dstSize == 8) { append(c, ldrswi(dst->low, base, offset)); } else { + assertT(c, offset == (offset & (srcSize == 8 ? (~7) : (~3)))); append(c, ldri(dst->low, base, offset, srcSize)); } break; @@ -1238,7 +1259,8 @@ void moveAR(Context* c, unsigned dstSize, lir::RegisterPair* dst) { - assertT(c, srcSize == TargetBytesPerWord and dstSize == TargetBytesPerWord); + assertT(c, srcSize == vm::TargetBytesPerWord + and dstSize == vm::TargetBytesPerWord); lir::Constant constant(src->address); moveCR(c, srcSize, &constant, dstSize, dst); @@ -1312,6 +1334,20 @@ void compareRM(Context* c, c->client->releaseTemporary(tmp.low); } +void compareMR(Context* c, + unsigned aSize, + lir::Memory* a, + unsigned bSize, + lir::RegisterPair* b) +{ + assertT(c, aSize == bSize); + + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); + moveMR(c, aSize, a, aSize, &tmp); + compareRR(c, aSize, &tmp, bSize, b); + c->client->releaseTemporary(tmp.low); +} + int32_t branch(Context* c, lir::TernaryOperation op) { switch (op) { @@ -1397,8 +1433,17 @@ void branchRM(Context* c, assertT(c, not isFloatBranch(op)); assertT(c, size <= vm::TargetBytesPerWord); - compareRM(c, size, a, size, b); - branch(c, op, target); + if (a->low.index() == 31) { + // stack overflow checks need to compare to the stack pointer, but + // we can only encode that in the opposite operand order we're + // given, so we need to reverse everything: + assertT(c, op == lir::JumpIfGreaterOrEqual); + compareMR(c, size, b, size, a); + branch(c, lir::JumpIfLess, target); + } else { + compareRM(c, size, a, size, b); + branch(c, op, target); + } } void branchCM(Context* c, @@ -1537,21 +1582,6 @@ void storeLoadBarrier(Context* c) memoryBarrier(c); } -bool needJump(MyBlock*) -{ - return false; -} - -unsigned padding(MyBlock*, unsigned) -{ - return 0; -} - -void resolve(MyBlock*) -{ - // ignore -} - } // namespace arm } // namespace codegen } // namespace avian diff --git a/src/compile-arm64.S b/src/compile-arm64.S index 65f76df6f3..744e6cd71e 100644 --- a/src/compile-arm64.S +++ b/src/compile-arm64.S @@ -16,11 +16,11 @@ #define BYTES_PER_WORD 4 #define LOCAL(x) .L##x - + #ifdef __APPLE__ # define GLOBAL(x) _##x #else -# define GLOBAL(x) x +# define GLOBAL(x) x #endif #define CONTINUATION_NEXT 4 @@ -29,7 +29,7 @@ #define CONTINUATION_FRAME_POINTER_OFFSET 24 #define CONTINUATION_LENGTH 28 #define CONTINUATION_BODY 32 - + .globl GLOBAL(vmInvoke) .align 2 GLOBAL(vmInvoke): @@ -89,8 +89,7 @@ GLOBAL(vmInvoke_returnAddress): // MyProcess::getStackTrace in compile.cpp for details on how we get // a reliable stack trace from a thread that might be interrupted at // any point in its execution. - mov x5, #0 - str x5, [x19, #TARGET_THREAD_STACK] + str xzr, [x19, #TARGET_THREAD_STACK] .globl GLOBAL(vmInvoke_safeStack) .align 2 @@ -100,11 +99,10 @@ GLOBAL(vmInvoke_safeStack): #error todo #endif // AVIAN_CONTINUATIONS - mov x5, #0 - str x5, [x19, #TARGET_THREAD_STACK] + str xzr, [x19, #TARGET_THREAD_STACK] // restore return type - ldr w5, [sp], #4 + ldr w5, [sp,#16]! // restore callee-saved register values ldp x19, x20, [sp,#16] @@ -112,7 +110,7 @@ GLOBAL(vmInvoke_safeStack): ldp x23, x24, [sp,#48] ldp x25, x26, [sp,#64] ldp x27, x28, [sp,#80] - ldp x29, x30, [sp],#96 + ldp x29, x30, [sp,#96]! LOCAL(vmInvoke_return): br x30 From 78735b35a8c8be1eb6d283f33eabca578f97b9be Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 23 Dec 2014 21:09:43 -0700 Subject: [PATCH 43/70] more ARM64 bugfixes, more passing tests --- src/codegen/target/arm/assembler.cpp | 23 +++++++++--- src/codegen/target/arm/operations64.cpp | 47 +++++++++++-------------- src/compile-arm64.S | 4 +-- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index b4046223e1..a50c36d173 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -89,11 +89,11 @@ void nextFrame(ArchitectureContext* con, void** stack) { assertT(con, *ip >= start); - assertT(con, *ip <= start + (size / TargetBytesPerWord)); + assertT(con, *ip <= start + (size / 4)); uint32_t* instruction = static_cast(*ip); - if ((*start >> 20) == 0xe59) { + if ((*start >> 20) == (TargetBytesPerWord == 8 ? 0xf94 : 0xe59)) { // skip stack overflow check start += 3; } @@ -111,7 +111,8 @@ void nextFrame(ArchitectureContext* con, return; } - if (*instruction == 0xe12fff1e) { // return + if (*instruction == (TargetBytesPerWord == 8 ? 0xd61f03c0 : 0xe12fff1e)) { + // return *ip = link; return; } @@ -124,7 +125,21 @@ void nextFrame(ArchitectureContext* con, // check for post-non-tail-call stack adjustment of the form "sub // sp, sp, #offset": - if ((*instruction >> 12) == 0xe24dd) { + if (TargetBytesPerWord == 8 and (*instruction & 0xff0003ff) == 0xd10003ff) + { + unsigned value = (*instruction >> 10) & 0xfff; + unsigned shift = (*instruction >> 22) & 1; + switch (shift) { + case 0: + offset -= value; + break; + case 1: + offset -= value << 12; + break; + default: + abort(con); + } + } else if (TargetBytesPerWord == 4 and (*instruction >> 12) == 0xe24dd) { unsigned value = *instruction & 0xff; unsigned rotation = (*instruction >> 8) & 0xf; switch (rotation) { diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 32a31cf2f5..a1c5e3c23b 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -378,7 +378,7 @@ uint32_t ldrshi(Register Rd, Register Rn, int offset) uint32_t ldrswi(Register Rd, Register Rn, int offset) { - return 0xb9800000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); + return 0xb9800000 | ((offset >> 2) << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t ldri(Register Rd, Register Rn, int offset, unsigned size) @@ -642,7 +642,7 @@ void moveCR2(Context* c, c->client->releaseTemporary(tmp.low); } else if (src->value->resolved()) { int64_t value = src->value->value(); - if (value > 0) { + if (value >= 0) { append(c, movz(dst->low, value & 0xFFFF, 0, size)); if (value >> 16) { append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); @@ -695,7 +695,7 @@ void subR(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - append(c, sub(dst->low, a->low, b->low, size)); + append(c, sub(dst->low, b->low, a->low, size)); } void addC(Context* c, @@ -1137,6 +1137,7 @@ void load(Context* c, case 4: case 8: if (signExtend and srcSize == 4 and dstSize == 8) { + assertT(c, offset == (offset & (~3))); append(c, ldrswi(dst->low, base, offset)); } else { assertT(c, offset == (offset & (srcSize == 8 ? (~7) : (~3)))); @@ -1293,17 +1294,24 @@ void compareCR(Context* c, { assertT(c, aSize == bSize); - int32_t v = a->value->value(); - if (v) { - if (v > 0 and v < 0x1000) { + if (!isFpr(b) && a->value->resolved()) { + int32_t v = a->value->value(); + if (v == 0) { + append(c, cmp(b->low, Register(31), aSize)); + return; + } else if (v > 0 and v < 0x1000) { append(c, cmpi(b->low, v, 0, aSize)); + return; } else if (v > 0 and v < 0x1000000 and v % 0x1000 == 0) { append(c, cmpi(b->low, v >> 12, 12, aSize)); - } else { - // todo - abort(c); + return; } } + + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); + moveCR(c, aSize, a, bSize, &tmp); + compareRR(c, bSize, &tmp, bSize, b); + c->client->releaseTemporary(tmp.low); } void compareCM(Context* c, @@ -1474,23 +1482,10 @@ void moveCM(Context* c, unsigned dstSize, lir::Memory* dst) { - switch (dstSize) { - case 8: { - lir::Constant srcHigh(shiftMaskPromise(c, src->value, 32, 0xFFFFFFFF)); - lir::Constant srcLow(shiftMaskPromise(c, src->value, 0, 0xFFFFFFFF)); - - lir::Memory dstLow(dst->base, dst->offset + 4, dst->index, dst->scale); - - moveCM(c, 4, &srcLow, 4, &dstLow); - moveCM(c, 4, &srcHigh, 4, dst); - } break; - - default: - lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); - moveCR(c, srcSize, src, dstSize, &tmp); - moveRM(c, dstSize, &tmp, dstSize, dst); - c->client->releaseTemporary(tmp.low); - } + lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK)); + moveCR(c, srcSize, src, dstSize, &tmp); + moveRM(c, dstSize, &tmp, dstSize, dst); + c->client->releaseTemporary(tmp.low); } void negateRR(Context* c, diff --git a/src/compile-arm64.S b/src/compile-arm64.S index 744e6cd71e..e319aa744e 100644 --- a/src/compile-arm64.S +++ b/src/compile-arm64.S @@ -102,7 +102,7 @@ GLOBAL(vmInvoke_safeStack): str xzr, [x19, #TARGET_THREAD_STACK] // restore return type - ldr w5, [sp,#16]! + ldr w5, [sp],#16 // restore callee-saved register values ldp x19, x20, [sp,#16] @@ -110,7 +110,7 @@ GLOBAL(vmInvoke_safeStack): ldp x23, x24, [sp,#48] ldp x25, x26, [sp,#64] ldp x27, x28, [sp,#80] - ldp x29, x30, [sp,#96]! + ldp x29, x30, [sp],#96 LOCAL(vmInvoke_return): br x30 From 85fcbb82b31fd9c6d18f6dcc398421ad6bce8d64 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 24 Dec 2014 08:12:36 -0700 Subject: [PATCH 44/70] more ARM64 bugfixes --- src/codegen/target/arm/operations64.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index a1c5e3c23b..f6fcddee5b 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -122,7 +122,7 @@ uint32_t fmovFdRn(Register Fd, Register Rn, unsigned size) uint32_t orr(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0xaa0003e0 : 0x2a0003e0) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0xaa000000 : 0x2a000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } uint32_t addi(Register Rd, Register Rn, int value, int shift, unsigned size) @@ -368,12 +368,12 @@ uint32_t ldrsbi(Register Rd, Register Rn, int offset) uint32_t ldrhi(Register Rd, Register Rn, int offset) { - return 0x79400000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); + return 0x79400000 | ((offset >> 1) << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t ldrshi(Register Rd, Register Rn, int offset) { - return 0x79c00000 | (offset << 10) | (Rn.index() << 5) | Rd.index(); + return 0x79c00000 | ((offset >> 1) << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t ldrswi(Register Rd, Register Rn, int offset) @@ -653,7 +653,7 @@ void moveCR2(Context* c, } } } - } else if (value < 0) { + } else { append(c, movn(dst->low, (~value) & 0xFFFF, 0, size)); if (~(value >> 16)) { append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); @@ -986,6 +986,7 @@ void store(Context* c, break; case 2: + assertT(c, offset == (offset & (~1))); append(c, strhi(src->low, base, offset)); break; @@ -1127,6 +1128,7 @@ void load(Context* c, break; case 2: + assertT(c, offset == (offset & (~1))); if (signExtend) { append(c, ldrshi(dst->low, base, offset)); } else { From 67f5461d82bf7f700b82fa1f3c34d5ae9d2a9af3 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 24 Dec 2014 10:05:20 -0700 Subject: [PATCH 45/70] more ARM64 bugfixes --- src/codegen/target/arm/operations64.cpp | 40 +++++++++++++++---------- src/compile-arm64.S | 4 +-- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index f6fcddee5b..b8f6c13221 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -38,17 +38,17 @@ void append(Context* c, uint32_t instruction) uint32_t lslv(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x9ac12000 : 0x1ac02000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x9ac02000 : 0x1ac02000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); } uint32_t ubfm(Register Rd, Register Rn, int r, int s, unsigned size) { - return (size == 8 ? 0xd3608000 : 0x53000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0xd3400000 : 0x53000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t sbfm(Register Rd, Register Rn, int r, int s, unsigned size) { - return (size == 8 ? 0x93408000 : 0x13000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x93400000 : 0x13000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t lsli(Register Rd, Register Rn, int shift, unsigned size) @@ -501,9 +501,9 @@ void shiftLeftC(Context* c, { uint64_t value = a->value->value(); if (size == 4 and (value & 0x1F)) { - append(c, lsli(dst->low, b->low, value, 4)); + append(c, lsli(dst->low, b->low, value & 0x1F, 4)); } else if (size == 8 and (value & 0x3F)) { - append(c, lsli(dst->low, b->low, value, 8)); + append(c, lsli(dst->low, b->low, value & 0x3F, 8)); } else { moveRR(c, size, b, size, dst); } @@ -526,9 +526,9 @@ void shiftRightC(Context* c, { uint64_t value = a->value->value(); if (size == 4 and (value & 0x1F)) { - append(c, lsri(dst->low, b->low, value, 4)); + append(c, asri(dst->low, b->low, value & 0x1F, 4)); } else if (size == 8 and (value & 0x3F)) { - append(c, lsri(dst->low, b->low, value, 8)); + append(c, asri(dst->low, b->low, value & 0x3F, 8)); } else { moveRR(c, size, b, size, dst); } @@ -551,9 +551,9 @@ void unsignedShiftRightC(Context* c, { uint64_t value = a->value->value(); if (size == 4 and (value & 0x1F)) { - append(c, asri(dst->low, b->low, value, 4)); + append(c, lsri(dst->low, b->low, value & 0x1F, 4)); } else if (size == 8 and (value & 0x3F)) { - append(c, asri(dst->low, b->low, value, 8)); + append(c, lsri(dst->low, b->low, value & 0x3F, 8)); } else { moveRR(c, size, b, size, dst); } @@ -645,9 +645,13 @@ void moveCR2(Context* c, if (value >= 0) { append(c, movz(dst->low, value & 0xFFFF, 0, size)); if (value >> 16) { - append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); + if ((value >> 16) & 0xFFFF) { + append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); + } if (value >> 32) { - append(c, movk(dst->low, (value >> 32) & 0xFFFF, 32, size)); + if ((value >> 32) & 0xFFFF) { + append(c, movk(dst->low, (value >> 32) & 0xFFFF, 32, size)); + } if (value >> 48) { append(c, movk(dst->low, (value >> 48) & 0xFFFF, 48, size)); } @@ -656,9 +660,13 @@ void moveCR2(Context* c, } else { append(c, movn(dst->low, (~value) & 0xFFFF, 0, size)); if (~(value >> 16)) { - append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); + if (((value >> 16) & 0xFFFF) != 0xFFFF) { + append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size)); + } if (~(value >> 32)) { - append(c, movk(dst->low, (value >> 32) & 0xFFFF, 32, size)); + if (((value >> 32) & 0xFFFF) != 0xFFFF) { + append(c, movk(dst->low, (value >> 32) & 0xFFFF, 32, size)); + } if (~(value >> 48)) { append(c, movk(dst->low, (value >> 48) & 0xFFFF, 48, size)); } @@ -704,7 +712,7 @@ void addC(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - int32_t v = a->value->value(); + int64_t v = a->value->value(); if (v) { if (v > 0 and v < 0x1000) { append(c, addi(dst->low, b->low, v, 0, size)); @@ -725,7 +733,7 @@ void subC(Context* c, lir::RegisterPair* b, lir::RegisterPair* dst) { - int32_t v = a->value->value(); + int64_t v = a->value->value(); if (v) { if (v > 0 and v < 0x1000) { append(c, subi(dst->low, b->low, v, 0, size)); @@ -1297,7 +1305,7 @@ void compareCR(Context* c, assertT(c, aSize == bSize); if (!isFpr(b) && a->value->resolved()) { - int32_t v = a->value->value(); + int64_t v = a->value->value(); if (v == 0) { append(c, cmp(b->low, Register(31), aSize)); return; diff --git a/src/compile-arm64.S b/src/compile-arm64.S index e319aa744e..62816ccf9f 100644 --- a/src/compile-arm64.S +++ b/src/compile-arm64.S @@ -13,7 +13,7 @@ .text -#define BYTES_PER_WORD 4 +#define BYTES_PER_WORD 8 #define LOCAL(x) .L##x @@ -59,7 +59,7 @@ GLOBAL(vmInvoke): // copy arguments into place sub sp, sp, w3, uxtw - mov x5, #0 + mov x4, #0 b LOCAL(vmInvoke_argumentTest) LOCAL(vmInvoke_argumentLoop): From 3e2545e5a7127c6d370c36563e3b4fb9e4bca82b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 08:02:37 -0700 Subject: [PATCH 46/70] more ARM64 bugfixes --- src/codegen/target/arm/assembler.cpp | 2 +- src/codegen/target/arm/operations64.cpp | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index a50c36d173..1ff070bcea 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -582,7 +582,7 @@ class MyArchitecture : public Architecture { case lir::FloatMultiply: case lir::FloatDivide: if (vfpSupported()) { - bMask.typeMask = lir::Operand::RegisterPairMask; + aMask.typeMask = lir::Operand::RegisterPairMask; aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); bMask = aMask; } else { diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index b8f6c13221..529c1d0bd0 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -259,9 +259,9 @@ uint32_t fcvtasWdSn(Register Rd, Register Fn) return 0x1e240000 | (Fn.index() << 5) | Rd.index(); } -uint32_t scvtfDdWn(Register Fd, Register Rn) +uint32_t scvtfDdXn(Register Fd, Register Rn) { - return 0x1e620000 | (Rn.index() << 5) | Fd.index(); + return 0x9e620000 | (Rn.index() << 5) | Fd.index(); } uint32_t scvtfSdWn(Register Fd, Register Rn) @@ -287,8 +287,8 @@ uint32_t strh(Register Rs, Register Rn, Register Rm) uint32_t striFs(Register Fs, Register Rn, int offset, unsigned size) { - return (size == 8 ? 0xfc000000 : 0xbc000000) | (offset << 16) - | (Rn.index() << 5) | Fs.index(); + return (size == 8 ? 0xfd000000 : 0xbd000000) + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Fs.index(); } uint32_t str(Register Rs, Register Rn, Register Rm, unsigned size) @@ -352,8 +352,8 @@ uint32_t ldr(Register Rd, Register Rn, Register Rm, unsigned size) uint32_t ldriFd(Register Fd, Register Rn, int offset, unsigned size) { - return (size == 8 ? 0xfc400000 : 0xbc400000) | (offset << 16) - | (Rn.index() << 5) | Fd.index(); + return (size == 8 ? 0xfd400000 : 0xbd400000) + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Fd.index(); } uint32_t ldrbi(Register Rd, Register Rn, int offset) @@ -808,9 +808,9 @@ void int2FloatRR(Context* c, lir::RegisterPair* b) { if (size == 8) { - append(c, scvtfDdWn(fpr(a), b->low)); + append(c, scvtfDdXn(fpr(b), a->low)); } else { - append(c, scvtfSdWn(fpr(a), b->low)); + append(c, scvtfSdWn(fpr(b), a->low)); } } @@ -981,6 +981,7 @@ void store(Context* c, switch (size) { case 4: case 8: + assertT(c, offset == (offset & (size == 8 ? (~7) : (~3)))); append(c, striFs(fpr(src->low), base, offset, size)); break; @@ -1119,6 +1120,7 @@ void load(Context* c, switch (srcSize) { case 4: case 8: + assertT(c, offset == (offset & (srcSize == 8 ? (~7) : (~3)))); append(c, ldriFd(fpr(dst->low), base, offset, srcSize)); break; From d37cb93d5021433eef04a2aedaada1a780593b61 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 10:00:51 -0700 Subject: [PATCH 47/70] remove redundant class qualifiers from Classes.java --- classpath/avian/Classes.java | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/classpath/avian/Classes.java b/classpath/avian/Classes.java index 34877d5ef2..3fc9f37144 100644 --- a/classpath/avian/Classes.java +++ b/classpath/avian/Classes.java @@ -38,7 +38,7 @@ public class Classes { public static native VMClass primitiveClass(char name); public static native void initialize(VMClass vmClass); - + public static native boolean isAssignableFrom(VMClass a, VMClass b); public static native VMClass getVMClass(Object o); @@ -134,7 +134,7 @@ public class Classes { array[i] = parseAnnotationValue(loader, pool, in); } return array; - } + } default: throw new AssertionError(); } @@ -207,7 +207,7 @@ public class Classes { while (spec[end] != ';') ++ end; ++ end; break; - + default: ++ end; } @@ -295,9 +295,9 @@ public class Classes { } Class c = loader.loadClass(name); VMClass vmc = SystemClassLoader.vmClass(c); - Classes.link(vmc, loader); + link(vmc, loader); if (initialize) { - Classes.initialize(vmc); + initialize(vmc); } return c; } @@ -315,7 +315,7 @@ public class Classes { } else { if (name.length() == 1) { return SystemClassLoader.getClass - (Classes.primitiveClass(name.charAt(0))); + (primitiveClass(name.charAt(0))); } else { throw new ClassNotFoundException(name); } @@ -378,7 +378,7 @@ public class Classes { public static int findField(VMClass vmClass, String name) { if (vmClass.fieldTable != null) { - Classes.link(vmClass); + link(vmClass); for (int i = 0; i < vmClass.fieldTable.length; ++i) { if (toString(vmClass.fieldTable[i].name).equals(name)) { @@ -426,7 +426,7 @@ public class Classes { { VMMethod[] methodTable = vmClass.methodTable; if (methodTable != null) { - Classes.link(vmClass); + link(vmClass); if (parameterTypes == null) { parameterTypes = new Class[0]; @@ -464,7 +464,7 @@ public class Classes { Method[] array = new Method[countMethods(vmClass, publicOnly)]; VMMethod[] methodTable = vmClass.methodTable; if (methodTable != null) { - Classes.link(vmClass); + link(vmClass); int ai = 0; for (int i = 0, j = declaredMethodCount(vmClass); i < j; ++i) { @@ -498,7 +498,7 @@ public class Classes { public static Field[] getFields(VMClass vmClass, boolean publicOnly) { Field[] array = new Field[countFields(vmClass, publicOnly)]; if (vmClass.fieldTable != null) { - Classes.link(vmClass); + link(vmClass); int ai = 0; for (int i = 0; i < vmClass.fieldTable.length; ++i) { @@ -568,9 +568,9 @@ public class Classes { return new ProtectionDomain(source, p); } - + public static native Method makeMethod(Class c, int slot); - + public static native Field makeField(Class c, int slot); private static native void acquireClassLock(); From 98a1fefefc348df4ab4c2581236d09ba2c9cbdd5 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 10:02:30 -0700 Subject: [PATCH 48/70] fix offset encoding for strhi instruction --- src/codegen/target/arm/operations64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 529c1d0bd0..401915f5ce 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -304,7 +304,7 @@ uint32_t strbi(Register Rs, Register Rn, int offset) uint32_t strhi(Register Rs, Register Rn, int offset) { - return 0x79000000 | (offset << 10) | (Rn.index() << 5) | Rs.index(); + return 0x79000000 | ((offset >> 1) << 10) | (Rn.index() << 5) | Rs.index(); } uint32_t stri(Register Rs, Register Rn, int offset, unsigned size) From e3f50e6d67e5e4010384ab6b63fad530e6c368a8 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 11:04:27 -0700 Subject: [PATCH 49/70] fix ARM64 OffsetPromise::value I must have done a search-and-replace from 4 to TargetBytesPerWord earlier, but in this case it should have been the instruction size (4), not the word size. --- src/codegen/target/arm/assembler.cpp | 2 ++ src/codegen/target/arm/fixup.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 1ff070bcea..d34f9992f1 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -981,6 +981,8 @@ class MyAssembler : public Assembler { bool jump = needJump(b); if (jump) { + expect(&con, TargetBytesPerWord == 4); + write4(dst + dstOffset, isa::b((poolSize + TargetBytesPerWord - 8) >> 2)); } diff --git a/src/codegen/target/arm/fixup.cpp b/src/codegen/target/arm/fixup.cpp index 7f5c0ff277..2e32813cbb 100644 --- a/src/codegen/target/arm/fixup.cpp +++ b/src/codegen/target/arm/fixup.cpp @@ -12,6 +12,12 @@ #include "fixup.h" #include "block.h" +namespace { + +const unsigned InstructionSize = 4; + +} // namespace + namespace avian { namespace codegen { namespace arm { @@ -39,7 +45,7 @@ int64_t OffsetPromise::value() unsigned o = offset - block->offset; return block->start - + padding(block, forTrace ? o - vm::TargetBytesPerWord : o) + o; + + padding(block, forTrace ? o - InstructionSize : o) + o; } Promise* offsetPromise(Context* con, bool forTrace) @@ -115,7 +121,7 @@ void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value) *p = (v & mask) | ((~mask) & *p); - return instruction + 4; + return instruction + InstructionSize; } ConstantPoolEntry::ConstantPoolEntry(Context* con, From cdcf173601bf3b4206b2370873dad55151c7ea34 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 12:09:53 -0700 Subject: [PATCH 50/70] format recent changes using clang-format --- src/codegen/target/arm/assembler.cpp | 3 +- src/codegen/target/arm/fixup.cpp | 5 +- src/codegen/target/arm/operations32.cpp | 41 ++++---------- src/codegen/target/arm/operations64.cpp | 75 +++++++++++++++---------- src/codegen/target/arm/registers.h | 4 +- 5 files changed, 61 insertions(+), 67 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index d34f9992f1..c9ddec0cc1 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -125,8 +125,7 @@ void nextFrame(ArchitectureContext* con, // check for post-non-tail-call stack adjustment of the form "sub // sp, sp, #offset": - if (TargetBytesPerWord == 8 and (*instruction & 0xff0003ff) == 0xd10003ff) - { + if (TargetBytesPerWord == 8 and (*instruction & 0xff0003ff) == 0xd10003ff) { unsigned value = (*instruction >> 10) & 0xfff; unsigned shift = (*instruction >> 22) & 1; switch (shift) { diff --git a/src/codegen/target/arm/fixup.cpp b/src/codegen/target/arm/fixup.cpp index 2e32813cbb..4413a399db 100644 --- a/src/codegen/target/arm/fixup.cpp +++ b/src/codegen/target/arm/fixup.cpp @@ -16,7 +16,7 @@ namespace { const unsigned InstructionSize = 4; -} // namespace +} // namespace namespace avian { namespace codegen { @@ -44,8 +44,7 @@ int64_t OffsetPromise::value() assertT(con, resolved()); unsigned o = offset - block->offset; - return block->start - + padding(block, forTrace ? o - InstructionSize : o) + o; + return block->start + padding(block, forTrace ? o - InstructionSize : o) + o; } Promise* offsetPromise(Context* con, bool forTrace) diff --git a/src/codegen/target/arm/operations32.cpp b/src/codegen/target/arm/operations32.cpp index 07dd7f0175..a16a0e0e24 100644 --- a/src/codegen/target/arm/operations32.cpp +++ b/src/codegen/target/arm/operations32.cpp @@ -417,9 +417,9 @@ void multiplyR(Context* con, if (size == 8) { bool useTemporaries = b->low == t->low; Register tmpLow = useTemporaries ? con->client->acquireTemporary(GPR_MASK) - : t->low; + : t->low; Register tmpHigh = useTemporaries ? con->client->acquireTemporary(GPR_MASK) - : t->high; + : t->high; emit(con, umull(tmpLow, tmpHigh, a->low, b->low)); emit(con, mla(tmpHigh, a->low, b->high, tmpHigh)); @@ -572,11 +572,11 @@ void floatDivideR(Context* con, } Register normalize(Context* con, - int offset, - Register index, - unsigned scale, - bool* preserveIndex, - bool* release) + int offset, + Register index, + unsigned scale, + bool* preserveIndex, + bool* release) { if (offset != 0 or scale != 1) { lir::RegisterPair normalizedIndex( @@ -854,26 +854,8 @@ void load(Context* con, case 8: { if (dstSize == 8) { lir::RegisterPair dstHigh(dst->high); - load(con, - 4, - base, - offset, - NoRegister, - 1, - 4, - &dstHigh, - false, - false); - load(con, - 4, - base, - offset + 4, - NoRegister, - 1, - 4, - dst, - false, - false); + load(con, 4, base, offset, NoRegister, 1, 4, &dstHigh, false, false); + load(con, 4, base, offset + 4, NoRegister, 1, 4, dst, false, false); } else { emit(con, ldri(dst->low, base, offset)); } @@ -1407,7 +1389,8 @@ void longJumpC(Context* con, unsigned size UNUSED, lir::Constant* target) { assertT(con, size == vm::TargetBytesPerWord); - lir::RegisterPair tmp(Register(4)); // a non-arg reg that we don't mind clobbering + lir::RegisterPair tmp( + Register(4)); // a non-arg reg that we don't mind clobbering moveCR2(con, vm::TargetBytesPerWord, target, &tmp, offsetPromise(con)); jumpR(con, vm::TargetBytesPerWord, &tmp); } @@ -1462,4 +1445,4 @@ void storeLoadBarrier(Context* con) } // namespace codegen } // namespace avian -#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM +#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 401915f5ce..ecd221a0bf 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -38,17 +38,20 @@ void append(Context* c, uint32_t instruction) uint32_t lslv(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x9ac02000 : 0x1ac02000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x9ac02000 : 0x1ac02000) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); } uint32_t ubfm(Register Rd, Register Rn, int r, int s, unsigned size) { - return (size == 8 ? 0xd3400000 : 0x53000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0xd3400000 : 0x53000000) | (r << 16) | (s << 10) + | (Rn.index() << 5) | Rd.index(); } uint32_t sbfm(Register Rd, Register Rn, int r, int s, unsigned size) { - return (size == 8 ? 0x93400000 : 0x13000000) | (r << 16) | (s << 10) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x93400000 : 0x13000000) | (r << 16) | (s << 10) + | (Rn.index() << 5) | Rd.index(); } uint32_t lsli(Register Rd, Register Rn, int shift, unsigned size) @@ -62,12 +65,14 @@ uint32_t lsli(Register Rd, Register Rn, int shift, unsigned size) uint32_t asrv(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x9ac02800 : 0x1ac02800) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x9ac02800 : 0x1ac02800) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); } uint32_t lsrv(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x9ac02400 : 0x1ac02400) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x9ac02400 : 0x1ac02400) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); } uint32_t lsri(Register Rd, Register Rn, int shift, unsigned size) @@ -122,37 +127,38 @@ uint32_t fmovFdRn(Register Fd, Register Rn, unsigned size) uint32_t orr(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0xaa000000 : 0x2a000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0xaa000000 : 0x2a000000) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); } uint32_t addi(Register Rd, Register Rn, int value, int shift, unsigned size) { return (size == 8 ? 0x91000000 : 0x11000000) | (shift ? 0x400000 : 0) - | (value << 10) | (Rn.index() << 5) | Rd.index(); + | (value << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t mov(Register Rd, Register Rn, unsigned size) { return Rn.index() == 31 ? addi(Rd, Rn, 0, 0, size) - : orr(Rd, Register(31), Rn, size); + : orr(Rd, Register(31), Rn, size); } uint32_t movz(Register Rd, int value, unsigned shift, unsigned size) { return (size == 8 ? 0xd2800000 : 0x52800000) | ((shift >> 4) << 21) - | (value << 5) | Rd.index(); + | (value << 5) | Rd.index(); } uint32_t movn(Register Rd, int value, unsigned shift, unsigned size) { return (size == 8 ? 0x92800000 : 0x12800000) | ((shift >> 4) << 21) - | (value << 5) | Rd.index(); + | (value << 5) | Rd.index(); } uint32_t movk(Register Rd, int value, unsigned shift, unsigned size) { return (size == 8 ? 0xf2800000 : 0x72800000) | ((shift >> 4) << 21) - | (value << 5) | Rd.index(); + | (value << 5) | Rd.index(); } uint32_t ldrPCRel(Register Rd, int offset, unsigned size) @@ -163,12 +169,14 @@ uint32_t ldrPCRel(Register Rd, int offset, unsigned size) uint32_t add(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0x8b000000 : 0x0b000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x8b000000 : 0x0b000000) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); } uint32_t sub(Register Rd, Register Rn, Register Rm, unsigned size) { - return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm.index() << 16) + | (Rn.index() << 5) | Rd.index(); } uint32_t and_(Register Rd, Register Rn, Register Rm, unsigned size) @@ -185,8 +193,8 @@ uint32_t eor(Register Rd, Register Rn, Register Rm, unsigned size) uint32_t madd(Register Rd, Register Rn, Register Rm, Register Ra, unsigned size) { - return (size == 8 ? 0x9b000000 : 0x1b000000) - | (Rm.index() << 16) | (Ra.index() << 10) | (Rn.index() << 5) | Rd.index(); + return (size == 8 ? 0x9b000000 : 0x1b000000) | (Rm.index() << 16) + | (Ra.index() << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t mul(Register Rd, Register Rn, Register Rm, unsigned size) @@ -197,7 +205,7 @@ uint32_t mul(Register Rd, Register Rn, Register Rm, unsigned size) uint32_t subi(Register Rd, Register Rn, int value, int shift, unsigned size) { return (size == 8 ? 0xd1000000 : 0x51000000) | (shift ? 0x400000 : 0) - | (value << 10) | (Rn.index() << 5) | Rd.index(); + | (value << 10) | (Rn.index() << 5) | Rd.index(); } uint32_t fabs_(Register Fd, Register Fn, unsigned size) @@ -288,7 +296,8 @@ uint32_t strh(Register Rs, Register Rn, Register Rm) uint32_t striFs(Register Fs, Register Rn, int offset, unsigned size) { return (size == 8 ? 0xfd000000 : 0xbd000000) - | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Fs.index(); + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) + | Fs.index(); } uint32_t str(Register Rs, Register Rn, Register Rm, unsigned size) @@ -310,7 +319,8 @@ uint32_t strhi(Register Rs, Register Rn, int offset) uint32_t stri(Register Rs, Register Rn, int offset, unsigned size) { return (size == 8 ? 0xf9000000 : 0xb9000000) - | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Rs.index(); + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) + | Rs.index(); } uint32_t ldrFd(Register Fd, Register Rn, Register Rm, unsigned size) @@ -353,7 +363,8 @@ uint32_t ldr(Register Rd, Register Rn, Register Rm, unsigned size) uint32_t ldriFd(Register Fd, Register Rn, int offset, unsigned size) { return (size == 8 ? 0xfd400000 : 0xbd400000) - | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Fd.index(); + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) + | Fd.index(); } uint32_t ldrbi(Register Rd, Register Rn, int offset) @@ -384,7 +395,8 @@ uint32_t ldrswi(Register Rd, Register Rn, int offset) uint32_t ldri(Register Rd, Register Rn, int offset, unsigned size) { return (size == 8 ? 0xf9400000 : 0xb9400000) - | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) | Rd.index(); + | ((offset >> (size == 8 ? 3 : 2)) << 10) | (Rn.index() << 5) + | Rd.index(); } uint32_t fcmp(Register Fn, Register Fm, unsigned size) @@ -1038,19 +1050,19 @@ void moveRM(Context* c, assertT(c, srcSize == dstSize); if (src->low.index() == 31) { - assertT(c, c->client == 0); // the compiler should never ask us to - // store the SP; we'll only get here - // when assembling a thunk + assertT(c, c->client == 0); // the compiler should never ask us to + // store the SP; we'll only get here + // when assembling a thunk - lir::RegisterPair tmp(Register(9)); // we're in a thunk, so we can - // clobber this + lir::RegisterPair tmp(Register(9)); // we're in a thunk, so we can + // clobber this moveRR(c, srcSize, src, srcSize, &tmp); store( - c, srcSize, &tmp, dst->base, dst->offset, dst->index, dst->scale, true); + c, srcSize, &tmp, dst->base, dst->offset, dst->index, dst->scale, true); } else { store( - c, srcSize, src, dst->base, dst->offset, dst->index, dst->scale, true); + c, srcSize, src, dst->base, dst->offset, dst->index, dst->scale, true); } } @@ -1272,8 +1284,9 @@ void moveAR(Context* c, unsigned dstSize, lir::RegisterPair* dst) { - assertT(c, srcSize == vm::TargetBytesPerWord - and dstSize == vm::TargetBytesPerWord); + assertT( + c, + srcSize == vm::TargetBytesPerWord and dstSize == vm::TargetBytesPerWord); lir::Constant constant(src->address); moveCR(c, srcSize, &constant, dstSize, dst); @@ -1288,7 +1301,7 @@ void compareRR(Context* c, unsigned bSize UNUSED, lir::RegisterPair* b) { - assertT(c, not (isFpr(a) xor isFpr(b))); + assertT(c, not(isFpr(a) xor isFpr(b))); assertT(c, aSize == bSize); if (isFpr(a)) { @@ -1593,4 +1606,4 @@ void storeLoadBarrier(Context* c) } // namespace codegen } // namespace avian -#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 +#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index 18622a81e5..d439ddc8ba 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -27,7 +27,7 @@ const unsigned MASK_LO8 = 0xff; constexpr Register ThreadRegister(19); constexpr Register StackRegister(31); constexpr Register LinkRegister(30); -constexpr Register ProgramCounter(0xFE); // i.e. unaddressable +constexpr Register ProgramCounter(0xFE); // i.e. unaddressable const int N_GPRS = 32; const int N_FPRS = 32; @@ -38,7 +38,7 @@ const RegisterMask FPR_MASK = 0xffffffff00000000; constexpr Register ThreadRegister(8); constexpr Register StackRegister(13); constexpr Register LinkRegister(14); -constexpr Register FrameRegister(0xFE); // i.e. there is none +constexpr Register FrameRegister(0xFE); // i.e. there is none constexpr Register ProgramCounter(15); const int N_GPRS = 16; From ea0a108cd220379ca1505c4d1393475387b3602e Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 12:16:28 -0700 Subject: [PATCH 51/70] add todo comment regarding integer division --- src/codegen/target/arm/assembler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index c9ddec0cc1..5d36fdf2f6 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -570,6 +570,11 @@ class MyArchitecture : public Architecture { aMask.typeMask = bMask.typeMask = lir::Operand::RegisterPairMask; break; + // todo: Although ARM has instructions for integer division and + // remainder, they don't trap on division by zero, which is why + // we use thunks. Alternatively, we could generate inline code + // with an explicit zero check, which would probably be a bit + // faster. case lir::Divide: case lir::Remainder: case lir::FloatRemainder: From d8b32f2c67f56c6f49f4c77c8abecea3f2226210 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 12:25:56 -0700 Subject: [PATCH 52/70] update CMakeLists.txt to fix CMake build --- src/codegen/target/arm/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/codegen/target/arm/CMakeLists.txt b/src/codegen/target/arm/CMakeLists.txt index bc26352adc..23faf6694f 100644 --- a/src/codegen/target/arm/CMakeLists.txt +++ b/src/codegen/target/arm/CMakeLists.txt @@ -4,5 +4,6 @@ add_library(avian_codegen_arm context.cpp fixup.cpp multimethod.cpp - operations.cpp + operations32.cpp + operations64.cpp ) From 8c277e2af89a848d12a66f6a094751f3ad443e32 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 14:47:31 -0700 Subject: [PATCH 53/70] conditionally compile ARM operations based on TARGET_BYTES_PER_WORD This fixes the codegen-targets=all build regression. --- src/codegen/target/arm/operations32.cpp | 4 ++-- src/codegen/target/arm/operations64.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen/target/arm/operations32.cpp b/src/codegen/target/arm/operations32.cpp index a16a0e0e24..77b5f2c6f9 100644 --- a/src/codegen/target/arm/operations32.cpp +++ b/src/codegen/target/arm/operations32.cpp @@ -15,7 +15,7 @@ #include "fixup.h" #include "multimethod.h" -#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM +#if TARGET_BYTES_PER_WORD == 4 namespace avian { namespace codegen { @@ -1445,4 +1445,4 @@ void storeLoadBarrier(Context* con) } // namespace codegen } // namespace avian -#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM +#endif // TARGET_BYTES_PER_WORD == 4 diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index ecd221a0bf..72291ea69c 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -14,7 +14,7 @@ #include "fixup.h" #include "multimethod.h" -#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 +#if TARGET_BYTES_PER_WORD == 8 namespace { @@ -1606,4 +1606,4 @@ void storeLoadBarrier(Context* c) } // namespace codegen } // namespace avian -#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 +#endif // TARGET_BYTES_PER_WORD == 8 From 76bfcaa8c099ff2f6987304e96008062eced817a Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Dec 2014 18:11:54 -0700 Subject: [PATCH 54/70] fix ARM64 bootimage=true build This fixes a problem with atomically updating JIT-compiled static calls to AOT-compiled code. It turns out there was also a problem with the 32-bit ARM code as well, but we never hit it because it is extremely unlikely that a code address can be loaded with a single immediate load instruction on 32-bit ARM since it can only handle numbers with 8 significant bits. I've fixed that as well. --- src/codegen/target/arm/assembler.cpp | 5 +++++ src/codegen/target/arm/operations32.cpp | 13 ++++++++++++- src/codegen/target/arm/operations64.cpp | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 5d36fdf2f6..831be22fe4 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -320,8 +320,13 @@ class MyArchitecture : public Architecture { case lir::AlignedLongCall: case lir::AlignedLongJump: { uint32_t* p = static_cast(returnAddress) - 2; +#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 + const int32_t mask = (PoolOffsetMask >> 2) << 5; + *reinterpret_cast(p + ((*p & mask) >> 5)) = newTarget; +#else *reinterpret_cast(p + (((*p & PoolOffsetMask) + 8) / 4)) = newTarget; +#endif } break; default: diff --git a/src/codegen/target/arm/operations32.cpp b/src/codegen/target/arm/operations32.cpp index 77b5f2c6f9..e9cd601fe3 100644 --- a/src/codegen/target/arm/operations32.cpp +++ b/src/codegen/target/arm/operations32.cpp @@ -317,7 +317,8 @@ void moveCR2(Context* con, lir::RegisterPair dstHi(dst->high); moveCR(con, 4, &srcLo, 4, dst); moveCR(con, 4, &srcHi, 4, &dstHi); - } else if (src->value->resolved() and isOfWidth(getValue(src), 8)) { + } else if (callOffset == 0 and src->value->resolved() + and isOfWidth(getValue(src), 8)) { emit(con, movi(dst->low, lo8(getValue(src)))); // fits in immediate } else { appendConstantPoolEntry(con, src->value, callOffset); @@ -1385,6 +1386,11 @@ void longCallC(Context* con, unsigned size UNUSED, lir::Constant* target) callR(con, vm::TargetBytesPerWord, &tmp); } +void alignedLongCallC(Context* con, unsigned size, lir::Constant* target) +{ + longCallC(con, size, target); +} + void longJumpC(Context* con, unsigned size UNUSED, lir::Constant* target) { assertT(con, size == vm::TargetBytesPerWord); @@ -1395,6 +1401,11 @@ void longJumpC(Context* con, unsigned size UNUSED, lir::Constant* target) jumpR(con, vm::TargetBytesPerWord, &tmp); } +void alignedLongJumpC(Context* con, unsigned size, lir::Constant* target) +{ + longJumpC(con, size, target); +} + void jumpC(Context* con, unsigned size UNUSED, lir::Constant* target) { assertT(con, size == vm::TargetBytesPerWord); diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 72291ea69c..5f3fc74df4 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -652,7 +652,7 @@ void moveCR2(Context* c, moveCR(c, size, src, size, &tmp); moveRR(c, size, &tmp, size, dst); c->client->releaseTemporary(tmp.low); - } else if (src->value->resolved()) { + } else if (callOffset == 0 and src->value->resolved()) { int64_t value = src->value->value(); if (value >= 0) { append(c, movz(dst->low, value & 0xFFFF, 0, size)); From e3ea60fc317fb40647a5157594ea984f9b08f46a Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 30 Dec 2014 09:37:26 -0700 Subject: [PATCH 55/70] fix ARM64 tails=true build --- src/codegen/target/arm/assembler.cpp | 22 +++++++++++--- src/codegen/target/arm/operations64.cpp | 40 +++++++++++++++++-------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index 831be22fe4..cb9f871f7e 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -130,10 +130,10 @@ void nextFrame(ArchitectureContext* con, unsigned shift = (*instruction >> 22) & 1; switch (shift) { case 0: - offset -= value; + offset -= value / TargetBytesPerWord; break; case 1: - offset -= value << 12; + offset -= (value << 12) / TargetBytesPerWord; break; default: abort(con); @@ -769,6 +769,11 @@ class MyAssembler : public Assembler { // how to handle them: assertT(&con, footprint < 256); + // todo: ARM64 frame allocation should be of the form: + // stp x29, x30, [sp,#size]! + // and deallocation should be of the form: + // ldp x29, x30, [sp],#size + lir::RegisterPair stack(StackRegister); ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); lir::Constant footprintConstant(&footprintPromise); @@ -875,10 +880,19 @@ class MyAssembler : public Assembler { return_(&con); } - virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint, + virtual void popFrameAndUpdateStackAndReturn(unsigned footprint, unsigned stackOffsetFromThread) { - popFrame(frameFootprint); + footprint += FrameHeaderSize; + + lir::RegisterPair returnAddress(LinkRegister); + lir::Memory returnAddressSrc(StackRegister, + (footprint - 1) * TargetBytesPerWord); + moveMR(&con, + TargetBytesPerWord, + &returnAddressSrc, + TargetBytesPerWord, + &returnAddress); lir::RegisterPair stack(StackRegister); lir::Memory newStackSrc(ThreadRegister, stackOffsetFromThread); diff --git a/src/codegen/target/arm/operations64.cpp b/src/codegen/target/arm/operations64.cpp index 5f3fc74df4..e0c4a69ed6 100644 --- a/src/codegen/target/arm/operations64.cpp +++ b/src/codegen/target/arm/operations64.cpp @@ -139,8 +139,8 @@ uint32_t addi(Register Rd, Register Rn, int value, int shift, unsigned size) uint32_t mov(Register Rd, Register Rn, unsigned size) { - return Rn.index() == 31 ? addi(Rd, Rn, 0, 0, size) - : orr(Rd, Register(31), Rn, size); + return Rn.index() == 31 or Rd.index() == 31 ? addi(Rd, Rn, 0, 0, size) + : orr(Rd, Register(31), Rn, size); } uint32_t movz(Register Rd, int value, unsigned shift, unsigned size) @@ -653,6 +653,10 @@ void moveCR2(Context* c, moveRR(c, size, &tmp, size, dst); c->client->releaseTemporary(tmp.low); } else if (callOffset == 0 and src->value->resolved()) { + // todo: Is it better performance-wise to load using immediate + // moves or via a PC-relative constant pool? Does it depend on + // how many significant bits there are? + int64_t value = src->value->value(); if (value >= 0) { append(c, movz(dst->low, value & 0xFFFF, 0, size)); @@ -1195,16 +1199,28 @@ void moveMR(Context* c, unsigned dstSize, lir::RegisterPair* dst) { - load(c, - srcSize, - src->base, - src->offset, - src->index, - src->scale, - dstSize, - dst, - true, - true); + if (dst->low.index() == 31) { + assertT(c, c->client == 0); // the compiler should never ask us to + // load the SP; we'll only get here + // when assembling a thunk + + lir::RegisterPair tmp(Register(9)); // we're in a thunk, so we can + // clobber this + + load(c, srcSize, src->base, src->offset, src->index, src->scale, dstSize, &tmp, true, true); + moveRR(c, dstSize, &tmp, dstSize, dst); + } else { + load(c, + srcSize, + src->base, + src->offset, + src->index, + src->scale, + dstSize, + dst, + true, + true); + } } void moveZMR(Context* c, From c9026a6053d015f6b37af3dbfa6a66ec6f80e417 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 30 Dec 2014 15:30:04 -0700 Subject: [PATCH 56/70] add continuations support for ARM64 Also, replace some preprocessor conditionals with C++ conditionals and add some todo comments and sample code for future work towards better ABI compatibility in the JIT compiled code. --- src/arm64.S | 2 + src/codegen/target/arm/assembler.cpp | 142 +++++++++++++++++---------- src/codegen/target/arm/fixup.cpp | 10 +- src/codegen/target/arm/fixup.h | 6 +- src/codegen/target/arm/registers.h | 3 +- src/compile-arm.S | 4 +- src/compile-arm64.S | 110 +++++++++++++++++++-- src/compile.cpp | 2 + 8 files changed, 204 insertions(+), 75 deletions(-) diff --git a/src/arm64.S b/src/arm64.S index 6953ea0cf6..b5ce9a5000 100644 --- a/src/arm64.S +++ b/src/arm64.S @@ -35,6 +35,7 @@ GLOBAL(vmNativeCall): // allocate frame stp x29, x30, [sp,#-64]! + mov x29, sp // save callee-saved register values so we can clobber them stp x19, x20, [sp,#16] @@ -118,6 +119,7 @@ GLOBAL(vmRun): // allocate frame stp x29, x30, [sp,#-96]! + mov x29, sp // save callee-saved register values stp x19, x20, [sp,#16] diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index cb9f871f7e..3130662073 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -232,6 +232,7 @@ class MyArchitecture : public Architecture { { switch (register_.index()) { case LinkRegister.index(): + case FrameRegister.index(): case StackRegister.index(): case ThreadRegister.index(): case ProgramCounter.index(): @@ -320,13 +321,13 @@ class MyArchitecture : public Architecture { case lir::AlignedLongCall: case lir::AlignedLongJump: { uint32_t* p = static_cast(returnAddress) - 2; -#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 - const int32_t mask = (PoolOffsetMask >> 2) << 5; - *reinterpret_cast(p + ((*p & mask) >> 5)) = newTarget; -#else - *reinterpret_cast(p + (((*p & PoolOffsetMask) + 8) / 4)) - = newTarget; -#endif + if (TargetBytesPerWord == 8) { + const int32_t mask = (PoolOffsetMask >> 2) << 5; + *reinterpret_cast(p + ((*p & mask) >> 5)) = newTarget; + } else { + *reinterpret_cast(p + (((*p & PoolOffsetMask) + 8) / 4)) + = newTarget; + } } break; default: @@ -769,24 +770,45 @@ class MyAssembler : public Assembler { // how to handle them: assertT(&con, footprint < 256); - // todo: ARM64 frame allocation should be of the form: - // stp x29, x30, [sp,#size]! - // and deallocation should be of the form: - // ldp x29, x30, [sp],#size + // todo: the ARM ABI says the frame preamble should be of the form + // + // stp x29, x30, [sp,#-footprint]! + // mov x29, sp + // + // and the frame should be popped with e.g. + // + // ldp x29, x30, [sp],#footprint + // br x30 + // + // However, that will invalidate a lot of assumptions elsewhere + // about the return address being stored at the opposite end of + // the frame, so lots of other code will need to change before we + // can do that. The code below can be enabled as a starting point + // when we're ready to tackle that. + if (false and TargetBytesPerWord == 8) { + // stp x29, x30, [sp,#-footprint]! + con.code.append4(0xa9800000 | ((-footprint & 0x7f) << 15) + | (StackRegister.index() << 5) + | (LinkRegister.index() << 10) | FrameRegister.index()); - lir::RegisterPair stack(StackRegister); - ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); - lir::Constant footprintConstant(&footprintPromise); - subC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); + lir::RegisterPair stack(StackRegister); + lir::RegisterPair frame(FrameRegister); + moveRR(&con, TargetBytesPerWord, &stack, TargetBytesPerWord, &frame); + } else { + lir::RegisterPair stack(StackRegister); + ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); + lir::Constant footprintConstant(&footprintPromise); + subC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); - lir::RegisterPair returnAddress(LinkRegister); - lir::Memory returnAddressDst(StackRegister, - (footprint - 1) * TargetBytesPerWord); - moveRM(&con, - TargetBytesPerWord, - &returnAddress, - TargetBytesPerWord, - &returnAddressDst); + lir::RegisterPair returnAddress(LinkRegister); + lir::Memory returnAddressDst(StackRegister, + (footprint - 1) * TargetBytesPerWord); + moveRM(&con, + TargetBytesPerWord, + &returnAddress, + TargetBytesPerWord, + &returnAddressDst); + } } virtual void adjustFrame(unsigned difference) @@ -801,19 +823,26 @@ class MyAssembler : public Assembler { { footprint += FrameHeaderSize; - lir::RegisterPair returnAddress(LinkRegister); - lir::Memory returnAddressSrc(StackRegister, - (footprint - 1) * TargetBytesPerWord); - moveMR(&con, - TargetBytesPerWord, - &returnAddressSrc, - TargetBytesPerWord, - &returnAddress); + // see comment regarding the ARM64 ABI in allocateFrame + if (false and TargetBytesPerWord == 8) { + // ldp x29, x30, [sp],#footprint + con.code.append4(0xa8c00000 | (footprint << 15) | (31 << 5) | (30 << 10) + | 29); + } else { + lir::RegisterPair returnAddress(LinkRegister); + lir::Memory returnAddressSrc(StackRegister, + (footprint - 1) * TargetBytesPerWord); + moveMR(&con, + TargetBytesPerWord, + &returnAddressSrc, + TargetBytesPerWord, + &returnAddress); - lir::RegisterPair stack(StackRegister); - ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); - lir::Constant footprintConstant(&footprintPromise); - addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); + lir::RegisterPair stack(StackRegister); + ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); + lir::Constant footprintConstant(&footprintPromise); + addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); + } } virtual void popFrameForTailCall(unsigned footprint, @@ -885,14 +914,21 @@ class MyAssembler : public Assembler { { footprint += FrameHeaderSize; - lir::RegisterPair returnAddress(LinkRegister); - lir::Memory returnAddressSrc(StackRegister, - (footprint - 1) * TargetBytesPerWord); - moveMR(&con, - TargetBytesPerWord, - &returnAddressSrc, - TargetBytesPerWord, - &returnAddress); + // see comment regarding the ARM64 ABI in allocateFrame + if (false and TargetBytesPerWord == 8) { + // ldp x29, x30, [sp],#footprint + con.code.append4(0xa8c00000 | (footprint << 15) | (31 << 5) | (30 << 10) + | 29); + } else { + lir::RegisterPair returnAddress(LinkRegister); + lir::Memory returnAddressSrc(StackRegister, + (footprint - 1) * TargetBytesPerWord); + moveMR(&con, + TargetBytesPerWord, + &returnAddressSrc, + TargetBytesPerWord, + &returnAddress); + } lir::RegisterPair stack(StackRegister); lir::Memory newStackSrc(ThreadRegister, stackOffsetFromThread); @@ -986,18 +1022,18 @@ class MyAssembler : public Assembler { int32_t* p = reinterpret_cast(dst + instruction); -#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 - int32_t v = entry - instruction; - expect(&con, v == (v & PoolOffsetMask)); + if (TargetBytesPerWord == 8) { + int32_t v = entry - instruction; + expect(&con, v == (v & PoolOffsetMask)); - const int32_t mask = (PoolOffsetMask >> 2) << 5; - *p = (((v >> 2) << 5) & mask) | ((~mask) & *p); -#else - int32_t v = (entry - 8) - instruction; - expect(&con, v == (v & PoolOffsetMask)); + const int32_t mask = (PoolOffsetMask >> 2) << 5; + *p = (((v >> 2) << 5) & mask) | ((~mask) & *p); + } else { + int32_t v = (entry - 8) - instruction; + expect(&con, v == (v & PoolOffsetMask)); - *p = (v & PoolOffsetMask) | ((~PoolOffsetMask) & *p); -#endif + *p = (v & PoolOffsetMask) | ((~PoolOffsetMask) & *p); + } poolSize += TargetBytesPerWord; } diff --git a/src/codegen/target/arm/fixup.cpp b/src/codegen/target/arm/fixup.cpp index 4413a399db..3117688b15 100644 --- a/src/codegen/target/arm/fixup.cpp +++ b/src/codegen/target/arm/fixup.cpp @@ -99,9 +99,9 @@ void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value) { int32_t* p = reinterpret_cast(instruction); -#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 int32_t v; int32_t mask; + if (vm::TargetBytesPerWord == 8) { if ((*p >> 24) == 0x54) { // conditional branch v = ((reinterpret_cast(value) - instruction) >> 2) << 5; @@ -111,10 +111,10 @@ void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value) v = (reinterpret_cast(value) - instruction) >> 2; mask = 0x3FFFFFF; } -#else - int32_t v = (reinterpret_cast(value) - (instruction + 8)) >> 2; - const int32_t mask = 0xFFFFFF; -#endif + } else { + v = (reinterpret_cast(value) - (instruction + 8)) >> 2; + mask = 0xFFFFFF; + } expect(s, bounded(0, 8, v)); diff --git a/src/codegen/target/arm/fixup.h b/src/codegen/target/arm/fixup.h index 2e9c0aca01..cce2b59dce 100644 --- a/src/codegen/target/arm/fixup.h +++ b/src/codegen/target/arm/fixup.h @@ -27,11 +27,7 @@ namespace arm { const bool DebugPool = false; -#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 -const int32_t PoolOffsetMask = 0x1FFFFF; -#else -const int32_t PoolOffsetMask = 0xFFF; -#endif +const int32_t PoolOffsetMask = vm::TargetBytesPerWord == 8 ? 0x1FFFFF : 0xFFF; class Task { public: diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index d439ddc8ba..3bf4dc4041 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -23,10 +23,11 @@ namespace arm { const uint64_t MASK_LO32 = 0xffffffff; const unsigned MASK_LO8 = 0xff; -#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 +#if TARGET_BYTES_PER_WORD == 8 constexpr Register ThreadRegister(19); constexpr Register StackRegister(31); constexpr Register LinkRegister(30); +constexpr Register FrameRegister(29); constexpr Register ProgramCounter(0xFE); // i.e. unaddressable const int N_GPRS = 32; diff --git a/src/compile-arm.S b/src/compile-arm.S index 2f566f9558..83703af607 100644 --- a/src/compile-arm.S +++ b/src/compile-arm.S @@ -109,7 +109,7 @@ GLOBAL(vmInvoke_safeStack): ldr r6,[r5,#CONTINUATION_LENGTH] lsl r6,r6,#2 neg r7,r6 - add r7,r7,#-80 + add r7,r7,#-80 // 80 bytes for callee-saved register values mov r4,sp str r4,[sp,r7]! @@ -167,10 +167,10 @@ LOCAL(vmInvoke_handleException): bx r7 LOCAL(vmInvoke_exit): -#endif // AVIAN_CONTINUATIONS mov ip, #0 str ip, [r8, #TARGET_THREAD_STACK] +#endif // AVIAN_CONTINUATIONS // restore return type ldr ip, [sp], #4 diff --git a/src/compile-arm64.S b/src/compile-arm64.S index 62816ccf9f..c1c9c942b2 100644 --- a/src/compile-arm64.S +++ b/src/compile-arm64.S @@ -23,12 +23,12 @@ # define GLOBAL(x) x #endif -#define CONTINUATION_NEXT 4 -#define CONTINUATION_ADDRESS 16 -#define CONTINUATION_RETURN_ADDRESS_OFFSET 20 -#define CONTINUATION_FRAME_POINTER_OFFSET 24 -#define CONTINUATION_LENGTH 28 -#define CONTINUATION_BODY 32 +#define CONTINUATION_NEXT 8 +#define CONTINUATION_ADDRESS 32 +#define CONTINUATION_RETURN_ADDRESS_OFFSET 40 +#define CONTINUATION_FRAME_POINTER_OFFSET 48 +#define CONTINUATION_LENGTH 56 +#define CONTINUATION_BODY 64 .globl GLOBAL(vmInvoke) .align 2 @@ -43,6 +43,7 @@ GLOBAL(vmInvoke): // allocate frame stp x29, x30, [sp,#-96]! + mov x29, sp // save callee-saved register values stp x19, x20, [sp,#16] @@ -96,11 +97,65 @@ GLOBAL(vmInvoke_returnAddress): GLOBAL(vmInvoke_safeStack): #ifdef AVIAN_CONTINUATIONS -#error todo -#endif // AVIAN_CONTINUATIONS + // call the next continuation, if any + ldr x5, [x19,#TARGET_THREAD_CONTINUATION] + cmp x5, xzr + b.eq LOCAL(vmInvoke_exit) + ldr x6, [x5,#CONTINUATION_LENGTH] + lsl x6, x6, #3 + neg x7, x6 + add x7, x7, #-128 // 128 bytes for callee-saved register values + mov x4, sp + add sp, sp, x7 + str x4, [sp] + + add x7, x5, #CONTINUATION_BODY + mov x11, xzr + b LOCAL(vmInvoke_continuationTest) + +LOCAL(vmInvoke_continuationLoop): + ldr x9, [x7,x11] + str x9, [sp,x11] + add x11, x11, #8 + +LOCAL(vmInvoke_continuationTest): + cmp x11, x6 + b.le LOCAL(vmInvoke_continuationLoop) + + ldr x7, [x5,#CONTINUATION_RETURN_ADDRESS_OFFSET] + adr x11, GLOBAL(vmInvoke_returnAddress) + str x11, [sp,x7] + + ldr x7, [x5,#CONTINUATION_NEXT] + str x7, [x19,#TARGET_THREAD_CONTINUATION] + + // call the continuation unless we're handling an exception + ldr x7, [x19,#TARGET_THREAD_EXCEPTION] + cmp x7, xzr + b.ne LOCAL(vmInvoke_handleException) + ldr x7, [x5,#CONTINUATION_ADDRESS] + br x7 + +LOCAL(vmInvoke_handleException): + // we're handling an exception - call the exception handler instead + str xzr, [x19,#TARGET_THREAD_EXCEPTION] + ldr x11, [x19,#TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT] + ldr x9, [sp] + neg x11, x11 + add sp, sp, x11 + str x9, [sp] + ldr x11, [x19,#TARGET_THREAD_EXCEPTIONOFFSET] + str x7, [sp,x11] + + ldr x7, [x19,#TARGET_THREAD_EXCEPTIONHANDLER] + br x7 + +LOCAL(vmInvoke_exit): str xzr, [x19, #TARGET_THREAD_STACK] +#endif // AVIAN_CONTINUATIONS + // restore return type ldr w5, [sp],#16 @@ -119,7 +174,44 @@ LOCAL(vmInvoke_return): .align 2 GLOBAL(vmJumpAndInvoke): #ifdef AVIAN_CONTINUATIONS -#error todo + // x0: thread + // x1: address + // x2: stack + // x3: argumentFootprint + // x4: arguments + // x5: frameSize + + // allocate new frame, adding room for callee-saved registers, plus + // 8 bytes of padding since the calculation of frameSize assumes 8 + // bytes have already been allocated to save the return address, + // which is not true in this case + sub x2, x2, x5 + sub x2, x2, #136 + + mov x19, x0 + + // copy arguments into place + mov x6, xzr + b LOCAL(vmJumpAndInvoke_argumentTest) + +LOCAL(vmJumpAndInvoke_argumentLoop): + ldr x12, [x4,x6] + str x12, [x2,x6] + add x6, x6, #4 + +LOCAL(vmJumpAndInvoke_argumentTest): + cmp x6, x3 + ble LOCAL(vmJumpAndInvoke_argumentLoop) + + // the arguments have been copied, so we can set the real stack + // pointer now + mov sp, x2 + + // set return address to vmInvoke_returnAddress + adr x30, GLOBAL(vmInvoke_returnAddress) + + br x1 + #else // not AVIAN_CONTINUATIONS // vmJumpAndInvoke should only be called when continuations are // enabled, so we force a crash if we reach here: diff --git a/src/compile.cpp b/src/compile.cpp index 47b55574e7..51790bb0b3 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2189,6 +2189,8 @@ GcContinuation* makeCurrentContinuation(MyThread* t, *targetIp = 0; while (*targetIp == 0) { + assertT(t, ip); + GcMethod* method = methodForIp(t, ip); if (method) { PROTECT(t, method); From 80ce92a99943365e5e61d8ef64b2b85b16ec2d66 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 30 Dec 2014 17:03:58 -0700 Subject: [PATCH 57/70] fix iOS ARM64 build --- makefile | 3 ++- src/compile-arm64.S | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/makefile b/makefile index 008a230901..9224471195 100755 --- a/makefile +++ b/makefile @@ -1655,7 +1655,8 @@ $(classpath-dep): $(classpath-sources) $(classpath-jar-dep) @echo "compiling classpath classes" @mkdir -p $(classpath-build) classes="$(shell $(MAKE) -s --no-print-directory build=$(build) \ - $(classpath-classes))"; if [ -n "$${classes}" ]; then \ + $(classpath-classes) arch=$(build-arch) platform=$(build-platform))"; \ + if [ -n "$${classes}" ]; then \ $(javac) -source 1.6 -target 1.6 \ -d $(classpath-build) -bootclasspath $(boot-classpath) \ $${classes}; fi diff --git a/src/compile-arm64.S b/src/compile-arm64.S index c1c9c942b2..98436a15a0 100644 --- a/src/compile-arm64.S +++ b/src/compile-arm64.S @@ -58,8 +58,11 @@ GLOBAL(vmInvoke): mov x5, sp str x5, [x0,#TARGET_THREAD_SCRATCH] - // copy arguments into place - sub sp, sp, w3, uxtw + // copy arguments into place, reserving enough space for them, plus + // alignment padding + sub x5, sp, w3, uxtw + and sp, x5, #-16 + mov x4, #0 b LOCAL(vmInvoke_argumentTest) From 7df56328d97987e1064cb992f718d8f8ff2e00dc Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 31 Dec 2014 08:17:12 -0700 Subject: [PATCH 58/70] update README.md to indicate ARM64 support --- README.md | 112 +++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 58752d4481..9277db18db 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ to use forward slashes in the path. $ export JAVA_HOME=$(/usr/libexec/java_home) $ make $ build/macosx-x86_64/avian -cp build/macosx-x86_64/test Hello - + #### on Windows (MSYS): $ git clone git@github.com:ReadyTalk/win64.git ../win64 $ export JAVA_HOME="C:/Program Files/Java/jdk1.7.0_45" @@ -59,10 +59,10 @@ Supported Platforms Avian can currently target the following platforms: - * Linux (i386, x86_64, and ARM) + * Linux (i386, x86_64, ARM, and ARM64) * Windows (i386 and x86_64) * Mac OS X (i386 and x86_64) - * Apple iOS (i386 and ARM) + * Apple iOS (i386, ARM, and ARM64) * FreeBSD (i386, x86_64) @@ -86,7 +86,7 @@ certain flags described below, all of which are optional. $ make \ platform={linux,windows,macosx,ios,freebsd} \ - arch={i386,x86_64,arm} \ + arch={i386,x86_64,arm,arm64} \ process={compile,interpret} \ mode={debug,debug-fast,fast,small} \ lzma= \ @@ -99,26 +99,26 @@ certain flags described below, all of which are optional. openjdk-src= \ android= - * `platform` - the target platform + * `platform` - the target platform * _default:_ output of $(uname -s | tr [:upper:] [:lower:]), -normalized in some cases (e.g. CYGWIN_NT-5.1 -> windows) +normalized in some cases (e.g. CYGWIN_NT-5.1 -> windows) - * `arch` - the target architecture + * `arch` - the target architecture * _default:_ output of $(uname -m), normalized in some cases (e.g. i686 -> i386) - * `process` - choice between pure interpreter or JIT compiler + * `process` - choice between pure interpreter or JIT compiler * _default:_ compile * `mode` - which set of compilation flags to use to determine optimization level, debug symbols, and whether to enable -assertions +assertions * _default:_ fast * `lzma` - if set, support use of LZMA to compress embedded JARs and boot images. The value of this option should be a directory containing a recent LZMA SDK (available [here](http://www.7-zip.org/sdk.html)). Currently, only version 9.20 of -the SDK has been tested, but other versions might work. +the SDK has been tested, but other versions might work. * _default:_ not set * `armv6` - if true, don't use any instructions newer than armv6. By @@ -129,42 +129,42 @@ memory barrier instructions to ensure cache coherency class library and ahead-of-time compiled methods. This option is only valid for process=compile builds. Note that you may need to specify both build-arch=x86_64 and arch=x86_64 on 64-bit systems -where "uname -m" prints "i386". +where "uname -m" prints "i386". * _default:_ false * `heapdump` - if true, implement avian.Machine.dumpHeap(String), which, when called, will generate a snapshot of the heap in a simple, ad-hoc format for memory profiling purposes. See -heapdump.cpp for details. +heapdump.cpp for details. * _default:_ false * `tails` - if true, optimize each tail call by replacing the caller's stack frame with the callee's. This convention ensures proper tail recursion, suitable for languages such as Scheme. This -option is only valid for process=compile builds. +option is only valid for process=compile builds. * _default:_ false * `continuations` - if true, support continuations via the avian.Continuations methods callWithCurrentContinuation and dynamicWind. See Continuations.java for details. This option is -only valid for process=compile builds. +only valid for process=compile builds. * _default:_ false * `use-clang` - if true, use LLVM's clang instead of GCC to build. Note that this does not currently affect cross compiles, only -native builds. +native builds. * _default:_ false * `openjdk` - if set, use the OpenJDK class library instead of the default Avian class library. See "Building with the OpenJDK Class -Library" below for details. +Library" below for details. * _default:_ not set * `openjdk-src` - if this and the openjdk option above are both set, build an embeddable VM using the OpenJDK class library. The JNI components of the OpenJDK class library will be built from the sources found under the specified directory. See "Building with -the OpenJDK Class Library" below for details. +the OpenJDK Class Library" below for details. * _default:_ not set * `android` - if set, use the Android class library instead of the @@ -184,7 +184,7 @@ Note that not all combinations of these flags are valid. For instance, non-jailbroken iOS devices do not allow JIT compilation, so only process=interpret or bootimage=true builds will run on such devices. See [here](https://github.com/ReadyTalk/hello-ios) for an -example of an Xcode project for iOS which uses Avian. +example of an Xcode project for iOS which uses Avian. If you are compiling for Windows, you may either cross-compile using MinGW or build natively on Windows under MSYS or Cygwin. @@ -366,7 +366,7 @@ the following, starting from the Avian directory: git clone https://android.googlesource.com/platform/bionic (cd bionic && \ git checkout 84983592ade3ec7d72d082262fb6646849979bfc) - + git clone https://android.googlesource.com/platform/system/core \ system/core (cd system/core && \ @@ -517,37 +517,37 @@ setting the boot classpath to "[bootJar]". $ cat >embedded-jar-main.cpp <("-Xbootclasspath:[bootJar]"); - + JavaVM* vm; void* env; JNI_CreateJavaVM(&vm, &env, &vmArgs); JNIEnv* e = static_cast(env); - + jclass c = e->FindClass("Hello"); if (not e->ExceptionCheck()) { jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V"); @@ -577,21 +577,21 @@ setting the boot classpath to "[bootJar]". for (int i = 1; i < ac; ++i) { e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i])); } - + e->CallStaticVoidMethod(c, m, a); } } } } - + int exitCode = 0; if (e->ExceptionCheck()) { exitCode = -1; e->ExceptionDescribe(); } - + vm->DestroyJavaVM(); - + return exitCode; } EOF @@ -745,13 +745,13 @@ containing them. See the previous example for instructions. $ cat >bootimage-main.cpp <("-Davian.bootimage=bootimageBin"); - + options[1].optionString = const_cast("-Davian.codeimage=codeimageBin"); - + JavaVM* vm; void* env; JNI_CreateJavaVM(&vm, &env, &vmArgs); JNIEnv* e = static_cast(env); - + jclass c = e->FindClass("Hello"); if (not e->ExceptionCheck()) { jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V"); @@ -817,25 +817,25 @@ containing them. See the previous example for instructions. for (int i = 1; i < ac; ++i) { e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i])); } - + e->CallStaticVoidMethod(c, m, a); } } } } - + int exitCode = 0; if (e->ExceptionCheck()) { exitCode = -1; e->ExceptionDescribe(); } - + vm->DestroyJavaVM(); - + return exitCode; } EOF - + $ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \ -D_JNI_IMPLEMENTATION_ -c bootimage-main.cpp -o main.o From f717d87e8c512c3207c5ae1e8ab2d8f99e1187a2 Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Fri, 2 Jan 2015 12:52:36 -0700 Subject: [PATCH 59/70] Add better publishing intended for Travis + establish packages for windows/linux builds --- .travis.yml | 31 +++++++++--- build.gradle | 8 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- test/ci.sh | 63 ++++++++++++++++++------ 4 files changed, 72 insertions(+), 32 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0d01043096..b96f48bcc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,27 @@ language: cpp + +before_install: + - sudo apt-get update -qq + - sudo apt-get install -y libc6-dev-i386 mingw-w64 gcc-mingw-w64-x86-64 g++-mingw-w64-i686 binutils-mingw-w64-x86-64 lib32z1-dev zlib1g-dev g++-mingw-w64-x86-64 + env: + matrix: + # - BUILD_STEP="jdk-test" + # - BUILD_STEP="test" + # - BUILD_STEP="mode=debug test" + # - BUILD_STEP="process=interpret test" + # - BUILD_STEP="mode=debug bootimage=true test" + # - BUILD_STEP="bootimage=true test" + # - BUILD_STEP="openjdk=$JAVA_HOME test" + # - BUILD_STEP="tails=true continuations=true heapdump=true test" + # - BUILD_STEP="codegen-targets=all test" + - BUILD_STEP="PUBLISH" global: - TERM=dumb - - secure: Pe7OLUvdk3DeTAShyaYsdAXBcnjdNOrtfTPt1mCP5+JKBUw3z0n7BpTgATVRBmkn866pDqxL0N3+jBgjKUpEpqOj23bTB2AeDdIzlYkFGvTd3GQQV1lMFn16I9LOgWJhkfICTJ1rIYiNf8xSkJoeKGB7eGUM0KGsTvelFfsaGVc= - # BINTRAY_USER - - secure: CauPpj2QrbgEaePEPQx+FDeZqc46HmWXHfdAyn+DA9g6np3RMyc+N/ESrJ9efc4E772rnxory2QRyyNffzi29ceNTpIzsIRDuk5WvvC+zePEsQm8kX1afsDK5g16QEvJN24jGSW9ci9uxuknqjeKVOukcFQdxssIyDe11tYWJeI= - # BINTRAY_API_KEY - - secure: Gao6KTkCbqrdCDI2hQswh1v+SpHBeF4hR1WXmCe9gjmPyJb731K2eWigQOrhPOw7Ns3nubo1FwCb5YevYmwPMLryh0f4sKJyqLL1MLbffNl5GttNF2oO3p73cJpgBfHdzabAMwAYGYbneqUZ0Qn4K8RkzXUaoBDv465KmZhqbA0= -script: "./test/ci.sh" -after_success: -- "./gradlew artifactoryPublish" + - secure: rh1utD4shKmYtokItuRYEF9WsfTnvZO5XqnTU4DHTS7quHHgLihtOO2/3+B+2W2hEd5Obr2or8zx+zmzWcNUyLokZ0j/FRLWSScNkLzTtm12pupLrncY+/g1NIdfbhn+OLRIzBz6zB6m6a2qWFEJ+bScUNGD/7wZVtzkujqlDEE= + - secure: j9DOzZMCYk/BzhKK9u4XMKpCzyGOsvP2cLTp6cXE7/tkWDAPVv6BFmeqNbiLTEqk0aGX+HYbY/2YVtpRZmDzfeWtnBFF5mL1Y1tgzx1Kf155C+P6rZgt5PiQTUdXlp2umuRifY1BbXAPc3DZ2UOPUjWKnLHVbZLQRgO1zimmMx8= + +matrix: + fast_finish: true + +script: ./test/ci.sh STEP ${BUILD_STEP} diff --git a/build.gradle b/build.gradle index 5ecf1afb07..0aad0b602a 100644 --- a/build.gradle +++ b/build.gradle @@ -107,12 +107,6 @@ model { operatingSystem SupportedOS.valueOf(platform.toUpperCase()) architecture "${arch}" } - if(platformArch != currentPlatformArch) { - create(currentPlatformArch) { - operatingSystem SupportedOS.CURRENT - architecture "${currentArch}" - } - } } tasks { @@ -235,7 +229,7 @@ publishing { artifact("${nativeBuildDir}/avian${binSuffix}") { name "avian" type publishBinSuffix - extension binSuffix + extension publishBinSuffix } artifact("${nativeBuildDir}/libavian.a") { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 84bf862c89..2ce5f17a6f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -#Thu Aug 28 14:47:06 MDT 2014 +#Fri Jan 02 11:31:32 MST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/test/ci.sh b/test/ci.sh index 7040c7b921..f318897bde 100755 --- a/test/ci.sh +++ b/test/ci.sh @@ -1,9 +1,11 @@ -#!/bin/sh +#!/usr/bin/env bash -set -e +set -eo pipefail root_dir=$(pwd) +flags="${@}" + run() { echo '===============================================' if [ ! $(pwd) = ${root_dir} ]; then @@ -23,10 +25,24 @@ run_cmake() { cd .. } -flags="${@}" +publish() { + local platforms="${1}" + local arches="${2}" + + local platform + for platform in ${platforms}; do + local arch + for arch in ${arches}; do + echo "------ Publishing ${platform}-${arch} ------" + ./gradlew artifactoryPublish -Pplatform=${platform} -Parch=${arch} + done + done +} has_flag() { - local arg=$1 + local arg=${1} + + local f for f in ${flags}; do local key=$(echo $f | awk -F '=' '{print $1}') if [ ${key} = ${arg} ]; then @@ -38,19 +54,34 @@ has_flag() { make_target=test -test `uname -o` = "Cygwin" || run_cmake -DCMAKE_BUILD_TYPE=Debug +if [[ "${1}" == "STEP" ]]; then + shift 1 + if [[ "${1}" == "PUBLISH" ]]; then + if [[ $(uname -s) == "Darwin" || ${TRAVIS_OS_NAME} == "osx" ]]; then + publish "macosx" "i386 x86_64" + elif [[ $(uname -s) == "Linux" ]]; then + publish "linux windows" "i386 x86_64" + fi + else + run make ${@} + fi +else + if [[ $(uname -o) != "Cygwin" ]]; then + run_cmake -DCMAKE_BUILD_TYPE=Debug + fi -run make jdk-test -run make ${flags} ${make_target} -run make ${flags} mode=debug ${make_target} -run make ${flags} process=interpret ${make_target} + run make jdk-test + run make ${flags} ${make_target} + run make ${flags} mode=debug ${make_target} + run make ${flags} process=interpret ${make_target} -(has_flag openjdk-src || ! has_flag openjdk) && \ - run make ${flags} mode=debug bootimage=true ${make_target} && \ - run make ${flags} bootimage=true ${make_target} + (has_flag openjdk-src || ! has_flag openjdk) && \ + run make ${flags} mode=debug bootimage=true ${make_target} && \ + run make ${flags} bootimage=true ${make_target} -(! has_flag openjdk && ! has_flag android) && \ - run make ${flags} openjdk=$JAVA_HOME ${make_target} + (! has_flag openjdk && ! has_flag android) && \ + run make ${flags} openjdk=$JAVA_HOME ${make_target} -run make ${flags} tails=true continuations=true heapdump=true ${make_target} -run make ${flags} codegen-targets=all + run make ${flags} tails=true continuations=true heapdump=true ${make_target} + run make ${flags} codegen-targets=all +fi From 7e5bcbea07bd1cf5424f99a1172c1c5c952b19c9 Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Fri, 2 Jan 2015 16:38:43 -0700 Subject: [PATCH 60/70] Add matrix build for all tests --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index b96f48bcc7..c4b64bf9d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,15 +6,15 @@ before_install: env: matrix: - # - BUILD_STEP="jdk-test" - # - BUILD_STEP="test" - # - BUILD_STEP="mode=debug test" - # - BUILD_STEP="process=interpret test" - # - BUILD_STEP="mode=debug bootimage=true test" - # - BUILD_STEP="bootimage=true test" - # - BUILD_STEP="openjdk=$JAVA_HOME test" - # - BUILD_STEP="tails=true continuations=true heapdump=true test" - # - BUILD_STEP="codegen-targets=all test" + - BUILD_STEP="jdk-test" + - BUILD_STEP="test" + - BUILD_STEP="mode=debug test" + - BUILD_STEP="process=interpret test" + - BUILD_STEP="mode=debug bootimage=true test" + - BUILD_STEP="bootimage=true test" + - BUILD_STEP="openjdk=$JAVA_HOME test" + - BUILD_STEP="tails=true continuations=true heapdump=true test" + - BUILD_STEP="codegen-targets=all test" - BUILD_STEP="PUBLISH" global: - TERM=dumb From 022efafbcc3a88f1885322c9c47a38cf92418c83 Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Fri, 2 Jan 2015 16:48:43 -0700 Subject: [PATCH 61/70] Only publish to oss.jfrog.org if TRAVIS_BRANCH is master --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 0aad0b602a..c71f410ced 100644 --- a/build.gradle +++ b/build.gradle @@ -243,6 +243,9 @@ publishing { } artifactoryPublish { + onlyIf { + System.env.'TRAVIS_BRANCH' == "master" + } dependsOn assemble } From ab83e852ffb42d55eeee57acd31c6411bf957a58 Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Fri, 2 Jan 2015 16:52:15 -0700 Subject: [PATCH 62/70] Remove Travis CI matrix for now (best utilized when/if we have other platforms/arches) --- .travis.yml | 12 ++---------- test/ci.sh | 15 +++++---------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index c4b64bf9d4..d0b12eeaee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,15 +6,7 @@ before_install: env: matrix: - - BUILD_STEP="jdk-test" - - BUILD_STEP="test" - - BUILD_STEP="mode=debug test" - - BUILD_STEP="process=interpret test" - - BUILD_STEP="mode=debug bootimage=true test" - - BUILD_STEP="bootimage=true test" - - BUILD_STEP="openjdk=$JAVA_HOME test" - - BUILD_STEP="tails=true continuations=true heapdump=true test" - - BUILD_STEP="codegen-targets=all test" + - BUILD_STEP="" - BUILD_STEP="PUBLISH" global: - TERM=dumb @@ -24,4 +16,4 @@ env: matrix: fast_finish: true -script: ./test/ci.sh STEP ${BUILD_STEP} +script: ./test/ci.sh ${BUILD_STEP} diff --git a/test/ci.sh b/test/ci.sh index f318897bde..b84cd7f812 100755 --- a/test/ci.sh +++ b/test/ci.sh @@ -54,16 +54,11 @@ has_flag() { make_target=test -if [[ "${1}" == "STEP" ]]; then - shift 1 - if [[ "${1}" == "PUBLISH" ]]; then - if [[ $(uname -s) == "Darwin" || ${TRAVIS_OS_NAME} == "osx" ]]; then - publish "macosx" "i386 x86_64" - elif [[ $(uname -s) == "Linux" ]]; then - publish "linux windows" "i386 x86_64" - fi - else - run make ${@} +if [[ "${1}" == "PUBLISH" ]]; then + if [[ $(uname -s) == "Darwin" || ${TRAVIS_OS_NAME} == "osx" ]]; then + publish "macosx" "i386 x86_64" + elif [[ $(uname -s) == "Linux" ]]; then + publish "linux windows" "i386 x86_64" fi else if [[ $(uname -o) != "Cygwin" ]]; then From d62d0aa9162706b896bbde8b22dd60308787b3d8 Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Fri, 2 Jan 2015 17:33:13 -0700 Subject: [PATCH 63/70] Make sure not to publish if we are a pull request too... --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c71f410ced..3534d3b3d1 100644 --- a/build.gradle +++ b/build.gradle @@ -244,7 +244,7 @@ publishing { artifactoryPublish { onlyIf { - System.env.'TRAVIS_BRANCH' == "master" + System.env.'TRAVIS_BRANCH' == "master" && !System.env.'TRAVIS_PULL_REQUEST'.toBoolean() } dependsOn assemble } From eafec7e850051cf3109a7b5e7fbb69e2f9eb26d9 Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Mon, 5 Jan 2015 11:31:01 -0700 Subject: [PATCH 64/70] Add mac publishing + testing - Move apt calls to ci script --- .travis.yml | 7 ++++--- test/ci.sh | 25 +++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index d0b12eeaee..67c618c89b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: cpp +cache: apt -before_install: - - sudo apt-get update -qq - - sudo apt-get install -y libc6-dev-i386 mingw-w64 gcc-mingw-w64-x86-64 g++-mingw-w64-i686 binutils-mingw-w64-x86-64 lib32z1-dev zlib1g-dev g++-mingw-w64-x86-64 +os: + - linux + - osx env: matrix: diff --git a/test/ci.sh b/test/ci.sh index b84cd7f812..76f3f4f766 100755 --- a/test/ci.sh +++ b/test/ci.sh @@ -6,6 +6,23 @@ root_dir=$(pwd) flags="${@}" +is-mac() { + if [[ $(uname -s) == "Darwin" || ${TRAVIS_OS_NAME} == "osx" ]]; then + return 0 + fi + return 1 +} + +install-deps() { + if is-mac; then + echo "------ Installing dependencies for Mac ------" + else + echo "------ Installing dependencies for Linux ------" + sudo apt-get update -qq + sudo apt-get install -y libc6-dev-i386 mingw-w64 gcc-mingw-w64-x86-64 g++-mingw-w64-i686 binutils-mingw-w64-x86-64 lib32z1-dev zlib1g-dev g++-mingw-w64-x86-64 + fi +} + run() { echo '===============================================' if [ ! $(pwd) = ${root_dir} ]; then @@ -52,10 +69,12 @@ has_flag() { return 1 } -make_target=test +### START ### + +install-deps if [[ "${1}" == "PUBLISH" ]]; then - if [[ $(uname -s) == "Darwin" || ${TRAVIS_OS_NAME} == "osx" ]]; then + if is-mac; then publish "macosx" "i386 x86_64" elif [[ $(uname -s) == "Linux" ]]; then publish "linux windows" "i386 x86_64" @@ -65,6 +84,8 @@ else run_cmake -DCMAKE_BUILD_TYPE=Debug fi + make_target=test + run make jdk-test run make ${flags} ${make_target} run make ${flags} mode=debug ${make_target} From bf23f58aae11a9d432e749e5ff5b63f7834c549a Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Tue, 6 Jan 2015 09:58:48 -0700 Subject: [PATCH 65/70] Exclude osx test runs for now (only publish) --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 67c618c89b..d18b9c7fd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,5 +16,8 @@ env: matrix: fast_finish: true + exclude: + - os: osx + env: BUILD_STEP="" script: ./test/ci.sh ${BUILD_STEP} From 394c5cacce092967d38fccee2f8a9c3b9160cccb Mon Sep 17 00:00:00 2001 From: Seth Goings Date: Sat, 10 Jan 2015 16:53:52 -0700 Subject: [PATCH 66/70] Adjust publish logic to adhere to Travis spec See the specifics here: http://docs.travis-ci.com/user/ci-environment/#Environment-variables --- build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3534d3b3d1..e83b1528a2 100644 --- a/build.gradle +++ b/build.gradle @@ -244,7 +244,9 @@ publishing { artifactoryPublish { onlyIf { - System.env.'TRAVIS_BRANCH' == "master" && !System.env.'TRAVIS_PULL_REQUEST'.toBoolean() + // TRAVIS_BRANCH reports master if it is a master build or a PR going to master + // TRAVIS_PULL_REQUEST reports false if not a pull request and the PR number if it is + System.env.'TRAVIS_BRANCH' == "master" && System.env.'TRAVIS_PULL_REQUEST' == "false" } dependsOn assemble } @@ -278,4 +280,4 @@ artifactory { task wrapper(type: Wrapper) { distributionUrl = 'http://services.gradle.org/distributions/gradle-2.0-bin.zip' -} \ No newline at end of file +} From 97734af72d994cfd4f7dfcd87ba9c3df852af216 Mon Sep 17 00:00:00 2001 From: Timofey Lagutin Date: Sat, 10 Jan 2015 22:29:57 +0300 Subject: [PATCH 67/70] classpath-openjdk: Fix getZipFileEntry() 'addSlash' argument was incorrectly understood: it is supposed to add slash only on retry (see ZIP_GetEntry2() zip_util.c in OpenJDK). --- src/classpath-openjdk.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index 6247eda6ca..a219ce3f2e 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -1576,6 +1576,10 @@ int64_t JNICALL ZipFile::Entry* find(ZipFile* file, const char* path, unsigned pathLength) { + if (pathLength > 0 && path[0] == '/') { + ++path; + --pathLength; + } unsigned i = hash(path) & (file->indexSize - 1); for (ZipFile::Entry* e = file->index[i]; e; e = e->next) { const uint8_t* p = e->start; @@ -1601,13 +1605,17 @@ int64_t JNICALL memcpy(RUNTIME_ARRAY_BODY(p), path->body().begin(), path->length()); RUNTIME_ARRAY_BODY(p)[path->length()] = 0; replace('\\', '/', RUNTIME_ARRAY_BODY(p)); - if (addSlash) { + + ZipFile::Entry *e = find(file, RUNTIME_ARRAY_BODY(p), path->length()); + + if (e == 0 and addSlash and RUNTIME_ARRAY_BODY(p)[path->length()] != '/') { RUNTIME_ARRAY_BODY(p)[path->length()] = '/'; RUNTIME_ARRAY_BODY(p)[path->length() + 1] = 0; + + e = find(file, RUNTIME_ARRAY_BODY(p), path->length()); } - return reinterpret_cast( - find(file, RUNTIME_ARRAY_BODY(p), path->length())); + return reinterpret_cast(e); } else { int64_t entry = cast(t, From da01d20c1973d5feca02f770bca647f9fc3ffc01 Mon Sep 17 00:00:00 2001 From: Timofey Lagutin Date: Sat, 10 Jan 2015 23:31:24 +0300 Subject: [PATCH 68/70] classpath-openjdk: Fix freeZipFileEntry() Those ZipFile::Entries are part of ZipFile instance itself and will fail to free(). See :1504 and :1520 in openZipFile(). --- src/classpath-openjdk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index 6247eda6ca..beb032c35c 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -1792,9 +1792,9 @@ void JNICALL freeZipFileEntry(Thread* t, GcMethod* method, uintptr_t* arguments) 0, file->file, entry->entry); - } - t->m->heap->free(entry, sizeof(ZipFile::Entry)); + t->m->heap->free(entry, sizeof(ZipFile::Entry)); + } } int64_t JNICALL From 4509e29abb448edc998a42facc72075f9631efa9 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 12 Jan 2015 09:54:11 -0700 Subject: [PATCH 69/70] fix method interception bug When we intercept a method (i.e. when the VM wants to run its own code instead of whatever the classpath provides for that method), we make a clone of the original method so we can later call it from the intercepting code if appropriate. We also set the ACC_NATIVE flag on the original method to ensure that our intercepting code is always used in preference to the classpath version. However, we need to set that flag *after* we make the clone, or else the clone will also have the ACC_NATIVE flag set, which is not what we want. We never noticed this before because classpath versions of all the methods we intercept as of Java 7 are either native or are never called from their VM-specified replacements. However, some of those native methods are non-native in later versions of Java, so the bug has become apparent. --- src/avian/classpath-common.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/avian/classpath-common.h b/src/avian/classpath-common.h index afc699383a..a45b4f01f3 100644 --- a/src/avian/classpath-common.h +++ b/src/avian/classpath-common.h @@ -611,11 +611,11 @@ void intercept(Thread* t, if (m) { PROTECT(t, m); - m->flags() |= ACC_NATIVE; - if (updateRuntimeData) { GcMethod* clone = methodClone(t, m); + m->flags() |= ACC_NATIVE; + // make clone private to prevent vtable updates at compilation // time. Otherwise, our interception might be bypassed by calls // through the vtable. @@ -628,6 +628,8 @@ void intercept(Thread* t, GcMethodRuntimeData* runtimeData = getMethodRuntimeData(t, m); runtimeData->setNative(t, native->as(t)); + } else { + m->flags() |= ACC_NATIVE; } } else { // If we can't find the method, just ignore it, since ProGuard may From 8ee7e8124afcc8bd62a44bdf3896dbe2da8c29bf Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 15 Jan 2015 17:08:40 -0700 Subject: [PATCH 70/70] fix broken interpreter build due to out-of-order class initialization When we initialize the vtables for bootstrap Java classes such as java.lang.NullPointerException (i.e. classes which the VM has built-in knowledge of), we assign the superclass's vtable to any class which has no declared virtual methods of its own. However, that vtable will be null if we haven't initialized the superclass yet. Therefore, we must order this process such that no class is initialized until after all its superclasses. --- src/tools/type-generator/main.cpp | 17 +++++++++++++++-- test/NullPointer.java | 6 ++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/tools/type-generator/main.cpp b/src/tools/type-generator/main.cpp index 32dcf6f7f0..c981d13194 100644 --- a/src/tools/type-generator/main.cpp +++ b/src/tools/type-generator/main.cpp @@ -1408,8 +1408,20 @@ void writeInitializations(Output* out, Module& module) } } -void writeJavaInitialization(Output* out, Class* cl) +void writeJavaInitialization(Output* out, + Class* cl, + std::set& alreadyInited) { + if (alreadyInited.find(cl) != alreadyInited.end()) { + return; + } + + alreadyInited.insert(cl); + + if (cl->super) { + writeJavaInitialization(out, cl->super, alreadyInited); + } + out->write("bootJavaClass(t, Gc::"); out->write(capitalize(cl->name)); out->write("Type, "); @@ -1436,10 +1448,11 @@ void writeJavaInitialization(Output* out, Class* cl) void writeJavaInitializations(Output* out, Module& module) { + std::set alreadyInited; for (const auto p : module.classes) { Class* cl = p.second; if (cl->javaName.size()) { - writeJavaInitialization(out, cl); + writeJavaInitialization(out, cl, alreadyInited); } } } diff --git a/test/NullPointer.java b/test/NullPointer.java index 6c6e5c7b50..8d3abdc6fa 100644 --- a/test/NullPointer.java +++ b/test/NullPointer.java @@ -16,6 +16,12 @@ public class NullPointer { } public static void main(String[] args) { + try { + ((Object) null).getClass(); + } catch (Exception e) { + e.printStackTrace(); + } + try { throw_(null); throw new RuntimeException();