diff options
| author | 2012-07-13 17:25:52 -0700 | |
|---|---|---|
| committer | 2012-07-20 17:21:18 -0700 | |
| commit | 703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203 (patch) | |
| tree | 652ceef30d52a13854c14bb0a6f586e96421f625 /src/compiler/codegen/GenCommon.cc | |
| parent | e6e0651c7f0480e18d648200f8958c3463e82a2f (diff) | |
Numerous fixes to enable PromoteRegs, though it's still broken.
- Fixed ThrowNullPointerFromCode launchpad to load the array length
directly into the necessary arg reg without clobbering the array
pointer, since that value may be live afterwards.
- genArrayPut use a temporary reg for bytes if the source reg is >= 4,
since x86 can't express this.
- Fixed the order that core regs are spilled and unspilled.
- Correctly emit instructions when base == rBP and disp == 0.
- Added checks to the compiler to ensure that byte opcodes aren't used
on registers that can't be byte accessed.
- Fixed generation of a number of ops which use byte opcodes, including
floating point comparison, int-to-byte, and and-int/lit16.
- Added rBP, rSI, and rDI to spill registers for the x86 jni compiler.
- Various fixes and additions to the x86 disassembler.
Change-Id: I365fe7dec5cc64d181248fd58e90789f100b45e7
Diffstat (limited to 'src/compiler/codegen/GenCommon.cc')
| -rw-r--r-- | src/compiler/codegen/GenCommon.cc | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc index b4b0f6a9e0..baa4b48bbe 100644 --- a/src/compiler/codegen/GenCommon.cc +++ b/src/compiler/codegen/GenCommon.cc @@ -898,22 +898,33 @@ void handleThrowLaunchpads(CompilationUnit *cUnit) funcOffset = ENTRYPOINT_OFFSET(pThrowNullPointerFromCode); break; case kThrowArrayBounds: -#if defined (TARGET_X86) - // x86 leaves the array pointer in v2, so load the array length that the handler expects - opRegMem(cUnit, kOpMov, v2, v2, Array::LengthOffset().Int32Value()); -#endif // Move v1 (array index) to rARG0 and v2 (array length) to rARG1 if (v2 != rARG0) { opRegCopy(cUnit, rARG0, v1); +#if defined (TARGET_X86) + // x86 leaves the array pointer in v2, so load the array length that the handler expects + opRegMem(cUnit, kOpMov, rARG1, v2, Array::LengthOffset().Int32Value()); +#else opRegCopy(cUnit, rARG1, v2); +#endif } else { if (v1 == rARG1) { // Swap v1 and v2, using rARG2 as a temp opRegCopy(cUnit, rARG2, v1); +#if defined (TARGET_X86) + // x86 leaves the array pointer in v2, so load the array length that the handler expects + opRegMem(cUnit, kOpMov, rARG1, v2, Array::LengthOffset().Int32Value()); +#else opRegCopy(cUnit, rARG1, v2); +#endif opRegCopy(cUnit, rARG0, rARG2); } else { +#if defined (TARGET_X86) + // x86 leaves the array pointer in v2, so load the array length that the handler expects + opRegMem(cUnit, kOpMov, rARG1, v2, Array::LengthOffset().Int32Value()); +#else opRegCopy(cUnit, rARG1, v2); +#endif opRegCopy(cUnit, rARG0, v1); } } @@ -1598,9 +1609,18 @@ void genArrayPut(CompilationUnit* cUnit, int optFlags, OpSize size, } else { rlSrc = loadValue(cUnit, rlSrc, regClass); } - storeBaseIndexedDisp(cUnit, rlArray.lowReg, rlIndex.lowReg, scale, - dataOffset, rlSrc.lowReg, rlSrc.highReg, size, - INVALID_SREG); + // If the src reg can't be byte accessed, move it to a temp first. + if ((size == kSignedByte || size == kUnsignedByte) && rlSrc.lowReg >= 4) { + int temp = oatAllocTemp(cUnit); + opRegCopy(cUnit, temp, rlSrc.lowReg); + storeBaseIndexedDisp(cUnit, rlArray.lowReg, rlIndex.lowReg, scale, + dataOffset, temp, INVALID_REG, size, + INVALID_SREG); + } else { + storeBaseIndexedDisp(cUnit, rlArray.lowReg, rlIndex.lowReg, scale, + dataOffset, rlSrc.lowReg, rlSrc.highReg, size, + INVALID_SREG); + } #else bool needsRangeCheck = (!(optFlags & MIR_IGNORE_RANGE_CHECK)); int regLen = INVALID_REG; |