From b7035d04421112a4585245f67bc564170ec45b29 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 15 Nov 2010 08:22:03 +0000 Subject: [PATCH] split out an encoder for memri operands, allowing a relocation to be plopped into the immediate field. This allows us to encode stuff like this: lbz r3, lo16(__ZL4init)(r4) ; globalopt.cpp:5 ; encoding: [0x88,0x64,A,A] ; fixup A - offset: 0, value: lo16(__ZL4init), kind: fixup_ppc_lo16 stw r3, lo16(__ZL1s)(r5) ; globalopt.cpp:6 ; encoding: [0x90,0x65,A,A] ; fixup A - offset: 0, value: lo16(__ZL1s), kind: fixup_ppc_lo16 With this, we should have a completely function MCCodeEmitter for PPC, wewt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119134 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCCodeEmitter.cpp | 63 ++++++++----------------- lib/Target/PowerPC/PPCInstr64Bit.td | 6 +-- lib/Target/PowerPC/PPCInstrFormats.td | 17 ++++++- lib/Target/PowerPC/PPCInstrInfo.td | 11 +++-- lib/Target/PowerPC/PPCMCCodeEmitter.cpp | 29 ++++++++++-- 5 files changed, 68 insertions(+), 58 deletions(-) diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 48848e3713a..46332158fb5 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -66,6 +66,7 @@ namespace { unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const; + unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const; const char *getPassName() const { return "PowerPC Machine Code Emitter"; } @@ -209,6 +210,22 @@ unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI, return 0; } +unsigned PPCCodeEmitter::getMemRIEncoding(const MachineInstr &MI, + unsigned OpNo) const { + // Encode (imm, reg) as a memri, which has the low 16-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 16; + + const MachineOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return (getMachineOpValue(MI, MO) & 0xFFFF) | RegBits; + + // Add a fixup for the displacement field. + MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low)); + return RegBits; +} + unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const { // Encode (imm, reg) as a memrix, which has the low 14-bits as the @@ -233,49 +250,9 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); } - if (MO.isImm()) - return MO.getImm(); - - if (MO.isGlobal() || MO.isSymbol() || MO.isCPI() || MO.isJTI()) { - unsigned Reloc = 0; - assert((TM.getRelocationModel() != Reloc::PIC_ || MovePCtoLROffset) && - "MovePCtoLR not seen yet?"); - switch (MI.getOpcode()) { - default: MI.dump(); llvm_unreachable("Unknown instruction for relocation!"); - // Loads. - case PPC::LBZ: - case PPC::LBZ8: - case PPC::LHA: - case PPC::LHA8: - case PPC::LHZ: - case PPC::LHZ8: - case PPC::LWZ: - case PPC::LWZ8: - case PPC::LFS: - case PPC::LFD: - - // Stores. - case PPC::STB: - case PPC::STB8: - case PPC::STH: - case PPC::STH8: - case PPC::STW: - case PPC::STW8: - case PPC::STFS: - case PPC::STFD: - Reloc = PPC::reloc_absolute_low; - break; - } - - MCE.addRelocation(GetRelocation(MO, Reloc)); - } else { -#ifndef NDEBUG - errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; -#endif - llvm_unreachable(0); - } - - return 0; + assert(MO.isImm() && + "Relocation required in an instruction that we cannot encode!"); + return MO.getImm(); } #include "PPCGenCodeEmitter.inc" diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index fada63dd8ce..6636b692719 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -493,7 +493,7 @@ def LWAX : XForm_1<31, 341, (outs G8RC:$rD), (ins memrr:$src), // Update forms. let mayLoad = 1 in -def LHAU8 : DForm_1<43, (outs G8RC:$rD, ptr_rc:$ea_result), (ins symbolLo:$disp, +def LHAU8 : DForm_1a<43, (outs G8RC:$rD, ptr_rc:$ea_result), (ins symbolLo:$disp, ptr_rc:$rA), "lhau $rD, $disp($rA)", LdStGeneral, []>, RegConstraint<"$rA = $ea_result">, @@ -614,14 +614,14 @@ def STDX : XForm_8<31, 149, (outs), (ins G8RC:$rS, memrr:$dst), let PPC970_Unit = 2 in { -def STBU8 : DForm_1<38, (outs ptr_rc:$ea_res), (ins G8RC:$rS, +def STBU8 : DForm_1a<38, (outs ptr_rc:$ea_res), (ins G8RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stbu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_truncsti8 G8RC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STHU8 : DForm_1<45, (outs ptr_rc:$ea_res), (ins G8RC:$rS, +def STHU8 : DForm_1a<45, (outs ptr_rc:$ea_res), (ins G8RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "sthu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, diff --git a/lib/Target/PowerPC/PPCInstrFormats.td b/lib/Target/PowerPC/PPCInstrFormats.td index 3949bd3d21c..84a15b1ca94 100644 --- a/lib/Target/PowerPC/PPCInstrFormats.td +++ b/lib/Target/PowerPC/PPCInstrFormats.td @@ -102,6 +102,19 @@ class DForm_1 opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : I { bits<5> A; + bits<21> Addr; + + let Pattern = pattern; + + let Inst{6-10} = A; + let Inst{11-15} = Addr{20-16}; // Base Reg + let Inst{16-31} = Addr{15-0}; // Displacement +} + +class DForm_1a opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I { + bits<5> A; bits<16> C; bits<5> B; @@ -112,6 +125,7 @@ class DForm_1 opcode, dag OOL, dag IOL, string asmstr, let Inst{16-31} = C; } + class DForm_2 opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : DForm_base; @@ -147,8 +161,7 @@ class DForm_4_zero opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : DForm_1 { let A = 0; - let B = 0; - let C = 0; + let Addr = 0; } class DForm_5 opcode, dag OOL, dag IOL, string asmstr, diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index a9b1d87f3f6..9abf92c94cc 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -316,6 +316,7 @@ def crbitm: Operand { def memri : Operand { let PrintMethod = "printMemRegImm"; let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg); + let EncoderMethod = "getMemRIEncoding"; } def memrr : Operand { let PrintMethod = "printMemRegReg"; @@ -763,33 +764,33 @@ def STFD : DForm_1<54, (outs), (ins F8RC:$rS, memri:$dst), // Unindexed (r+i) Stores with Update (preinc). let PPC970_Unit = 2 in { -def STBU : DForm_1<39, (outs ptr_rc:$ea_res), (ins GPRC:$rS, +def STBU : DForm_1a<39, (outs ptr_rc:$ea_res), (ins GPRC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stbu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_truncsti8 GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STHU : DForm_1<45, (outs ptr_rc:$ea_res), (ins GPRC:$rS, +def STHU : DForm_1a<45, (outs ptr_rc:$ea_res), (ins GPRC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "sthu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_truncsti16 GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STWU : DForm_1<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, +def STWU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stwu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_store GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STFSU : DForm_1<37, (outs ptr_rc:$ea_res), (ins F4RC:$rS, +def STFSU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins F4RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stfsu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_store F4RC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STFDU : DForm_1<37, (outs ptr_rc:$ea_res), (ins F8RC:$rS, +def STFDU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins F8RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stfdu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_store F8RC:$rS, ptr_rc:$ptrreg, diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp index 66c0bb72a9c..ea5275aa316 100644 --- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp @@ -66,6 +66,8 @@ public: SmallVectorImpl &Fixups) const; unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups) const; + unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups) const; unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups) const; unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, @@ -147,10 +149,29 @@ unsigned PPCMCCodeEmitter::getLO16Encoding(const MCInst &MI, unsigned OpNo, return 0; } +unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups) const { + // Encode (imm, reg) as a memri, which has the low 16-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 16; + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return (getMachineOpValue(MI, MO, Fixups) & 0xFFFF) | RegBits; + + // Add a fixup for the displacement field. + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_lo16)); + return RegBits; +} + + unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups) const { // Encode (imm, reg) as a memrix, which has the low 14-bits as the // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 14; const MCOperand &MO = MI.getOperand(OpNo); @@ -182,11 +203,9 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); } - if (MO.isImm()) - return MO.getImm(); - - // FIXME. - return 0; + assert(MO.isImm() && + "Relocation required in an instruction that we cannot encode!"); + return MO.getImm(); } -- 2.34.1