diff options
| -rw-r--r-- | compiler/dex/quick/arm/arm_lir.h | 34 | ||||
| -rw-r--r-- | compiler/dex/quick/arm/assemble_arm.cc | 21 |
2 files changed, 35 insertions, 20 deletions
diff --git a/compiler/dex/quick/arm/arm_lir.h b/compiler/dex/quick/arm/arm_lir.h index 6272555983..b95789ea54 100644 --- a/compiler/dex/quick/arm/arm_lir.h +++ b/compiler/dex/quick/arm/arm_lir.h @@ -556,22 +556,24 @@ enum ArmOpDmbOptions { // Instruction assembly field_loc kind. enum ArmEncodingKind { - kFmtUnused, // Unused field and marks end of formats. - kFmtBitBlt, // Bit string using end/start. - kFmtDfp, // Double FP reg. - kFmtSfp, // Single FP reg. - kFmtModImm, // Shifted 8-bit immed using [26,14..12,7..0]. - kFmtImm16, // Zero-extended immed using [26,19..16,14..12,7..0]. - kFmtImm6, // Encoded branch target using [9,7..3]0. - kFmtImm12, // Zero-extended immediate using [26,14..12,7..0]. - kFmtShift, // Shift descriptor, [14..12,7..4]. - kFmtLsb, // least significant bit using [14..12][7..6]. - kFmtBWidth, // bit-field width, encoded as width-1. - kFmtShift5, // Shift count, [14..12,7..6]. - kFmtBrOffset, // Signed extended [26,11,13,21-16,10-0]:0. - kFmtFPImm, // Encoded floating point immediate. - kFmtOff24, // 24-bit Thumb2 unconditional branch encoding. - kFmtSkip, // Unused field, but continue to next. + kFmtUnused, // Unused field and marks end of formats. + kFmtBitBlt, // Bit string using end/start. + kFmtLdmRegList, // Load multiple register list using [15,14,12..0]. + kFmtStmRegList, // Store multiple register list using [14,12..0]. + kFmtDfp, // Double FP reg. + kFmtSfp, // Single FP reg. + kFmtModImm, // Shifted 8-bit immed using [26,14..12,7..0]. + kFmtImm16, // Zero-extended immed using [26,19..16,14..12,7..0]. + kFmtImm6, // Encoded branch target using [9,7..3]0. + kFmtImm12, // Zero-extended immediate using [26,14..12,7..0]. + kFmtShift, // Shift descriptor, [14..12,7..4]. + kFmtLsb, // least significant bit using [14..12][7..6]. + kFmtBWidth, // bit-field width, encoded as width-1. + kFmtShift5, // Shift count, [14..12,7..6]. + kFmtBrOffset, // Signed extended [26,11,13,21-16,10-0]:0. + kFmtFPImm, // Encoded floating point immediate. + kFmtOff24, // 24-bit Thumb2 unconditional branch encoding. + kFmtSkip, // Unused field, but continue to next. }; // Struct used to define the snippet positions for each Thumb opcode. diff --git a/compiler/dex/quick/arm/assemble_arm.cc b/compiler/dex/quick/arm/assemble_arm.cc index 35c3597491..06d9dd53b5 100644 --- a/compiler/dex/quick/arm/assemble_arm.cc +++ b/compiler/dex/quick/arm/assemble_arm.cc @@ -560,12 +560,12 @@ const ArmEncodingMap ArmMir2Lir::EncodingMap[kArmLast] = { kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE1 | IS_MOVE, "vmov.f64 ", " !0S, !1S", 4, kFixupNone), ENCODING_MAP(kThumb2Ldmia, 0xe8900000, - kFmtBitBlt, 19, 16, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, + kFmtBitBlt, 19, 16, kFmtLdmRegList, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE0 | REG_DEF_LIST1 | IS_LOAD, "ldmia", "!0C!!, <!1R>", 4, kFixupNone), ENCODING_MAP(kThumb2Stmia, 0xe8800000, - kFmtBitBlt, 19, 16, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, + kFmtBitBlt, 19, 16, kFmtStmRegList, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE0 | REG_USE_LIST1 | IS_STORE, "stmia", "!0C!!, <!1R>", 4, kFixupNone), @@ -935,7 +935,7 @@ const ArmEncodingMap ArmMir2Lir::EncodingMap[kArmLast] = { IS_BINARY_OP | REG_DEF0 | REG_USE_PC | IS_LOAD_OFF, "ldr", "!0C, [r15pc, -#!1d]", 4, kFixupNone), ENCODING_MAP(kThumb2Stm, 0xe9000000, - kFmtBitBlt, 19, 16, kFmtBitBlt, 12, 0, kFmtUnused, -1, -1, + kFmtBitBlt, 19, 16, kFmtStmRegList, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_USE0 | REG_USE_LIST1 | IS_STORE, "stm", "!0C, <!1R>", 4, kFixupNone), @@ -992,7 +992,7 @@ const ArmEncodingMap ArmMir2Lir::EncodingMap[kArmLast] = { kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0 | REG_USE0 | NEEDS_FIXUP, "movt", "!0C, #!1M", 4, kFixupMovImmHST), ENCODING_MAP(kThumb2LdmiaWB, 0xe8b00000, - kFmtBitBlt, 19, 16, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, + kFmtBitBlt, 19, 16, kFmtLdmRegList, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE0 | REG_DEF_LIST1 | IS_LOAD, "ldmia", "!0C!!, <!1R>", 4, kFixupNone), @@ -1094,6 +1094,19 @@ uint8_t* ArmMir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { bits |= value; } else { switch (encoder->field_loc[i].kind) { + case kFmtLdmRegList: + value = (operand << encoder->field_loc[i].start) & + ((1 << (encoder->field_loc[i].end + 1)) - 1); + bits |= value; + DCHECK_EQ((bits & (1 << 13)), 0u); + break; + case kFmtStmRegList: + value = (operand << encoder->field_loc[i].start) & + ((1 << (encoder->field_loc[i].end + 1)) - 1); + bits |= value; + DCHECK_EQ((bits & (1 << 13)), 0u); + DCHECK_EQ((bits & (1 << 15)), 0u); + break; case kFmtSkip: break; // Nothing to do, but continue to next. case kFmtUnused: |