From: Jim Grosbach Date: Tue, 12 Oct 2010 17:11:26 +0000 (+0000) Subject: Add encoding information for the remainder of the generic arithmetic X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0de6ab3c43ed2143d661115dddf1480545236c91;p=oota-llvm.git Add encoding information for the remainder of the generic arithmetic ARM instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116313 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 2ed2bfac103..3d1ddda6721 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -472,10 +472,14 @@ multiclass AsI1_bin_irs opcod, string opc, // The register-immediate version is re-materializable. This is useful // in particular for taking the address of a local. let isReMaterializable = 1 in { - def ri : AsI1 { + def ri : AsI1 { + bits<4> Rd; + bits<4> Rn; let Inst{25} = 1; + let Inst{15-12} = Rd; + let Inst{19-16} = Rn; } } def rr : AsI1> 1) + << ARMII::SoRotImmShift; + + // Encode immed_8. + Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); + return Binary; +} MCCodeEmitter *llvm::createARMMCCodeEmitter(const Target &, TargetMachine &TM, @@ -112,12 +120,10 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind, unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO) const { if (MO.isReg()) - // FIXME: Should shifted register stuff be handled as part of this? Maybe. return getARMRegisterNumbering(MO.getReg()); - else if (MO.isImm()) - // FIXME: This is insufficient. Shifted immediates and all that... (blech). + else if (MO.isImm()) { return static_cast(MO.getImm()); - else { + } else { #ifndef NDEBUG errs() << MO; #endif @@ -142,31 +148,42 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, ++MCNumEmitted; // Keep track of the # of mi's emitted // FIXME: TableGen doesn't deal well with operands that expand to multiple // machine instruction operands, so for now we'll fix those up here. + // Similarly, operands that are encoded as other than their literal + // values in the MI. + unsigned Value = getBinaryCodeForInstr(MI); switch (Opcode) { + default: break; + case ARM::ADDri: + case ARM::ANDri: + case ARM::BICri: + case ARM::EORri: + case ARM::ORRri: + case ARM::SUBri: + // The 's' bit. + if (MI.getOperand(5).getReg() == ARM::CPSR) + Value |= 1 << ARMII::S_BitShift; + // The shifted immediate value. + Value |= getMachineSoImmOpValue((unsigned)MI.getOperand(2).getImm()); + break; case ARM::ADDrs: case ARM::ANDrs: case ARM::BICrs: case ARM::EORrs: case ARM::ORRrs: case ARM::SUBrs: { + // The 's' bit. + if (MI.getOperand(7).getReg() == ARM::CPSR) + Value |= 1 << ARMII::S_BitShift; // The so_reg operand needs the shift ammount encoded. - unsigned Value = getBinaryCodeForInstr(MI); unsigned ShVal = MI.getOperand(4).getImm(); unsigned ShType = ARM_AM::getShiftOpcEncoding(ARM_AM::getSORegShOp(ShVal)); unsigned ShAmt = ARM_AM::getSORegOffset(ShVal); - Value |= ShType << ARMII::ShiftTypeShift; Value |= ShAmt << ARMII::ShiftShift; - - EmitConstant(Value, 4, CurByte, OS); - break; - } - default: { - unsigned Value = getBinaryCodeForInstr(MI); - EmitConstant(Value, 4, CurByte, OS); break; } } + EmitConstant(Value, 4, CurByte, OS); } // FIXME: These #defines shouldn't be necessary. Instead, tblgen should diff --git a/test/MC/ARM/simple-encoding.ll b/test/MC/ARM/simple-encoding.ll index 4c23c7e7f26..f10e934a1e9 100644 --- a/test/MC/ARM/simple-encoding.ll +++ b/test/MC/ARM/simple-encoding.ll @@ -35,4 +35,15 @@ entry: ret i32 %add } +define i32 @f4(i32 %a, i32 %b) nounwind readnone ssp { +entry: +; CHECK: f4 +; CHECK: add r0, r0, #254, 28 @ encoding: [0xfe,0x0e,0x80,0xe2] +; CHECK: @ 4064 +; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1] + %add = add nsw i32 %a, 4064 + ret i32 %add +} + + declare void @llvm.trap() nounwind