From 17e2c188359769a1df18c42593a94ce0fc2a9a75 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 15 Nov 2010 08:02:41 +0000 Subject: [PATCH] add support for encoding the lo14 forms used for a few PPC64 addressing modes. For example, we now get: ld r3, lo16(_G)(r3) ; encoding: [0xe8,0x63,A,0bAAAAAA00] ; fixup A - offset: 0, value: lo16(_G), kind: fixup_ppc_lo14 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119133 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCCodeEmitter.cpp | 23 +++++++++++------------ lib/Target/PowerPC/PPCInstr64Bit.td | 9 +++++---- lib/Target/PowerPC/PPCInstrFormats.td | 22 ++++++++++++++++++---- lib/Target/PowerPC/PPCInstrInfo.td | 1 + lib/Target/PowerPC/PPCMCCodeEmitter.cpp | 15 ++++++++++----- 5 files changed, 45 insertions(+), 25 deletions(-) diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 9335b183dbd..48848e3713a 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -66,7 +66,7 @@ namespace { unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const; - unsigned getLO14Encoding(const MachineInstr &MI, unsigned OpNo) const; + unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const; const char *getPassName() const { return "PowerPC Machine Code Emitter"; } @@ -209,13 +209,19 @@ unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI, return 0; } -unsigned PPCCodeEmitter::getLO14Encoding(const MachineInstr &MI, - unsigned OpNo) const { +unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI, + unsigned OpNo) 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)) << 14; + const MachineOperand &MO = MI.getOperand(OpNo); - if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO); + if (MO.isImm()) + return (getMachineOpValue(MI, MO) & 0x3FFF) | RegBits; MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low_ix)); - return 0; + return RegBits; } @@ -259,13 +265,6 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, case PPC::STFD: Reloc = PPC::reloc_absolute_low; break; - - case PPC::LWA: - case PPC::LD: - case PPC::STD: - case PPC::STD_32: - Reloc = PPC::reloc_absolute_low_ix; - break; } MCE.addRelocation(GetRelocation(MO, Reloc)); diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 0b96bcd6357..fada63dd8ce 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -552,12 +552,13 @@ def LDtoc: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg), "", [(set G8RC:$rD, (PPCtoc_entry tglobaladdr:$disp, G8RC:$reg))]>, isPPC64; -let RST = 2, DS = 8 in + +let RST = 2, DS_RA = 0 in // FIXME: Should be a pseudo. def LDinto_toc: DSForm_1<58, 0, (outs), (ins G8RC:$reg), "ld 2, 8($reg)", LdStLD, [(PPCload_toc G8RC:$reg)]>, isPPC64; -let RST = 2, DS = 40, RA = 1 in +let RST = 2, DS_RA = 0 in // FIXME: Should be a pseudo. def LDtoc_restore : DSForm_1<58, 0, (outs), (ins), "ld 2, 40(1)", LdStLD, [(PPCtoc_restore)]>, isPPC64; @@ -628,8 +629,8 @@ def STHU8 : DForm_1<45, (outs ptr_rc:$ea_res), (ins G8RC:$rS, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STDU : DSForm_1<62, 1, (outs ptr_rc:$ea_res), (ins G8RC:$rS, - s16immX4:$ptroff, ptr_rc:$ptrreg), +def STDU : DSForm_1a<62, 1, (outs ptr_rc:$ea_res), (ins G8RC:$rS, + s16immX4:$ptroff, ptr_rc:$ptrreg), "stdu $rS, $ptroff($ptrreg)", LdStSTD, [(set ptr_rc:$ea_res, (pre_store G8RC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, diff --git a/lib/Target/PowerPC/PPCInstrFormats.td b/lib/Target/PowerPC/PPCInstrFormats.td index 4357bdccec7..3949bd3d21c 100644 --- a/lib/Target/PowerPC/PPCInstrFormats.td +++ b/lib/Target/PowerPC/PPCInstrFormats.td @@ -188,17 +188,31 @@ class DSForm_1 opcode, bits<2> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : I { bits<5> RST; - bits<14> DS; - bits<5> RA; + bits<19> DS_RA; let Pattern = pattern; let Inst{6-10} = RST; - let Inst{11-15} = RA; - let Inst{16-29} = DS; + let Inst{11-15} = DS_RA{18-14}; // Register # + let Inst{16-29} = DS_RA{13-0}; // Displacement. let Inst{30-31} = xo; } +class DSForm_1a opcode, bits<2> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I { + bits<5> RST; + bits<14> DS; + bits<5> RA; + + let Pattern = pattern; + + let Inst{6-10} = RST; + let Inst{11-15} = RA; + let Inst{16-29} = DS; + let Inst{30-31} = xo; +} + // 1.7.6 X-Form class XForm_base_r3xo opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 11f84d0d84c..a9b1d87f3f6 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -324,6 +324,7 @@ def memrr : Operand { def memrix : Operand { // memri where the imm is shifted 2 bits. let PrintMethod = "printMemRegImmShifted"; let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg); + let EncoderMethod = "getMemRIXEncoding"; } def tocentry : Operand { let MIOperandInfo = (ops i32imm:$imm); diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp index 644f46f21d8..66c0bb72a9c 100644 --- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp @@ -66,8 +66,8 @@ public: SmallVectorImpl &Fixups) const; unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups) const; - unsigned getLO14Encoding(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, SmallVectorImpl &Fixups) const; @@ -147,15 +147,20 @@ unsigned PPCMCCodeEmitter::getLO16Encoding(const MCInst &MI, unsigned OpNo, return 0; } -unsigned PPCMCCodeEmitter::getLO14Encoding(const MCInst &MI, unsigned OpNo, +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 #. + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 14; + const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups); + if (MO.isImm()) + return (getMachineOpValue(MI, MO, Fixups) & 0x3FFF) | RegBits; // Add a fixup for the branch target. Fixups.push_back(MCFixup::Create(0, MO.getExpr(), (MCFixupKind)PPC::fixup_ppc_lo14)); - return 0; + return RegBits; }