forked from OSchip/llvm-project
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. llvm-svn: 119134
This commit is contained in:
parent
8f4444d003
commit
efacb9ee42
|
@ -66,6 +66,7 @@ namespace {
|
||||||
|
|
||||||
unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
unsigned getLO16Encoding(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;
|
unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
|
|
||||||
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
|
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
|
||||||
|
@ -209,6 +210,22 @@ unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI,
|
||||||
return 0;
|
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 PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI,
|
||||||
unsigned OpNo) const {
|
unsigned OpNo) const {
|
||||||
// Encode (imm, reg) as a memrix, which has the low 14-bits as the
|
// 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());
|
return PPCRegisterInfo::getRegisterNumbering(MO.getReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MO.isImm())
|
assert(MO.isImm() &&
|
||||||
return MO.getImm();
|
"Relocation required in an instruction that we cannot encode!");
|
||||||
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "PPCGenCodeEmitter.inc"
|
#include "PPCGenCodeEmitter.inc"
|
||||||
|
|
|
@ -493,7 +493,7 @@ def LWAX : XForm_1<31, 341, (outs G8RC:$rD), (ins memrr:$src),
|
||||||
|
|
||||||
// Update forms.
|
// Update forms.
|
||||||
let mayLoad = 1 in
|
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),
|
ptr_rc:$rA),
|
||||||
"lhau $rD, $disp($rA)", LdStGeneral,
|
"lhau $rD, $disp($rA)", LdStGeneral,
|
||||||
[]>, RegConstraint<"$rA = $ea_result">,
|
[]>, 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 {
|
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),
|
symbolLo:$ptroff, ptr_rc:$ptrreg),
|
||||||
"stbu $rS, $ptroff($ptrreg)", LdStGeneral,
|
"stbu $rS, $ptroff($ptrreg)", LdStGeneral,
|
||||||
[(set ptr_rc:$ea_res,
|
[(set ptr_rc:$ea_res,
|
||||||
(pre_truncsti8 G8RC:$rS, ptr_rc:$ptrreg,
|
(pre_truncsti8 G8RC:$rS, ptr_rc:$ptrreg,
|
||||||
iaddroff:$ptroff))]>,
|
iaddroff:$ptroff))]>,
|
||||||
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
|
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),
|
symbolLo:$ptroff, ptr_rc:$ptrreg),
|
||||||
"sthu $rS, $ptroff($ptrreg)", LdStGeneral,
|
"sthu $rS, $ptroff($ptrreg)", LdStGeneral,
|
||||||
[(set ptr_rc:$ea_res,
|
[(set ptr_rc:$ea_res,
|
||||||
|
|
|
@ -102,6 +102,19 @@ class DForm_1<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
||||||
InstrItinClass itin, list<dag> pattern>
|
InstrItinClass itin, list<dag> pattern>
|
||||||
: I<opcode, OOL, IOL, asmstr, itin> {
|
: I<opcode, OOL, IOL, asmstr, itin> {
|
||||||
bits<5> A;
|
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<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
||||||
|
InstrItinClass itin, list<dag> pattern>
|
||||||
|
: I<opcode, OOL, IOL, asmstr, itin> {
|
||||||
|
bits<5> A;
|
||||||
bits<16> C;
|
bits<16> C;
|
||||||
bits<5> B;
|
bits<5> B;
|
||||||
|
|
||||||
|
@ -112,6 +125,7 @@ class DForm_1<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
||||||
let Inst{16-31} = C;
|
let Inst{16-31} = C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DForm_2<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
class DForm_2<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
||||||
InstrItinClass itin, list<dag> pattern>
|
InstrItinClass itin, list<dag> pattern>
|
||||||
: DForm_base<opcode, OOL, IOL, asmstr, itin, pattern>;
|
: DForm_base<opcode, OOL, IOL, asmstr, itin, pattern>;
|
||||||
|
@ -147,8 +161,7 @@ class DForm_4_zero<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
||||||
InstrItinClass itin, list<dag> pattern>
|
InstrItinClass itin, list<dag> pattern>
|
||||||
: DForm_1<opcode, OOL, IOL, asmstr, itin, pattern> {
|
: DForm_1<opcode, OOL, IOL, asmstr, itin, pattern> {
|
||||||
let A = 0;
|
let A = 0;
|
||||||
let B = 0;
|
let Addr = 0;
|
||||||
let C = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DForm_5<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
class DForm_5<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
||||||
|
|
|
@ -316,6 +316,7 @@ def crbitm: Operand<i8> {
|
||||||
def memri : Operand<iPTR> {
|
def memri : Operand<iPTR> {
|
||||||
let PrintMethod = "printMemRegImm";
|
let PrintMethod = "printMemRegImm";
|
||||||
let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg);
|
let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg);
|
||||||
|
let EncoderMethod = "getMemRIEncoding";
|
||||||
}
|
}
|
||||||
def memrr : Operand<iPTR> {
|
def memrr : Operand<iPTR> {
|
||||||
let PrintMethod = "printMemRegReg";
|
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).
|
// Unindexed (r+i) Stores with Update (preinc).
|
||||||
let PPC970_Unit = 2 in {
|
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),
|
symbolLo:$ptroff, ptr_rc:$ptrreg),
|
||||||
"stbu $rS, $ptroff($ptrreg)", LdStGeneral,
|
"stbu $rS, $ptroff($ptrreg)", LdStGeneral,
|
||||||
[(set ptr_rc:$ea_res,
|
[(set ptr_rc:$ea_res,
|
||||||
(pre_truncsti8 GPRC:$rS, ptr_rc:$ptrreg,
|
(pre_truncsti8 GPRC:$rS, ptr_rc:$ptrreg,
|
||||||
iaddroff:$ptroff))]>,
|
iaddroff:$ptroff))]>,
|
||||||
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
|
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),
|
symbolLo:$ptroff, ptr_rc:$ptrreg),
|
||||||
"sthu $rS, $ptroff($ptrreg)", LdStGeneral,
|
"sthu $rS, $ptroff($ptrreg)", LdStGeneral,
|
||||||
[(set ptr_rc:$ea_res,
|
[(set ptr_rc:$ea_res,
|
||||||
(pre_truncsti16 GPRC:$rS, ptr_rc:$ptrreg,
|
(pre_truncsti16 GPRC:$rS, ptr_rc:$ptrreg,
|
||||||
iaddroff:$ptroff))]>,
|
iaddroff:$ptroff))]>,
|
||||||
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
|
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),
|
symbolLo:$ptroff, ptr_rc:$ptrreg),
|
||||||
"stwu $rS, $ptroff($ptrreg)", LdStGeneral,
|
"stwu $rS, $ptroff($ptrreg)", LdStGeneral,
|
||||||
[(set ptr_rc:$ea_res, (pre_store GPRC:$rS, ptr_rc:$ptrreg,
|
[(set ptr_rc:$ea_res, (pre_store GPRC:$rS, ptr_rc:$ptrreg,
|
||||||
iaddroff:$ptroff))]>,
|
iaddroff:$ptroff))]>,
|
||||||
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
|
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),
|
symbolLo:$ptroff, ptr_rc:$ptrreg),
|
||||||
"stfsu $rS, $ptroff($ptrreg)", LdStGeneral,
|
"stfsu $rS, $ptroff($ptrreg)", LdStGeneral,
|
||||||
[(set ptr_rc:$ea_res, (pre_store F4RC:$rS, ptr_rc:$ptrreg,
|
[(set ptr_rc:$ea_res, (pre_store F4RC:$rS, ptr_rc:$ptrreg,
|
||||||
iaddroff:$ptroff))]>,
|
iaddroff:$ptroff))]>,
|
||||||
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
|
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),
|
symbolLo:$ptroff, ptr_rc:$ptrreg),
|
||||||
"stfdu $rS, $ptroff($ptrreg)", LdStGeneral,
|
"stfdu $rS, $ptroff($ptrreg)", LdStGeneral,
|
||||||
[(set ptr_rc:$ea_res, (pre_store F8RC:$rS, ptr_rc:$ptrreg,
|
[(set ptr_rc:$ea_res, (pre_store F8RC:$rS, ptr_rc:$ptrreg,
|
||||||
|
|
|
@ -66,6 +66,8 @@ public:
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo,
|
unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
|
unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
|
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
|
||||||
|
@ -147,10 +149,29 @@ unsigned PPCMCCodeEmitter::getLO16Encoding(const MCInst &MI, unsigned OpNo,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
|
SmallVectorImpl<MCFixup> &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,
|
unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
// Encode (imm, reg) as a memrix, which has the low 14-bits as the
|
// Encode (imm, reg) as a memrix, which has the low 14-bits as the
|
||||||
// displacement and the next 5 bits as the register #.
|
// 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;
|
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 14;
|
||||||
|
|
||||||
const MCOperand &MO = MI.getOperand(OpNo);
|
const MCOperand &MO = MI.getOperand(OpNo);
|
||||||
|
@ -182,11 +203,9 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
|
||||||
return PPCRegisterInfo::getRegisterNumbering(MO.getReg());
|
return PPCRegisterInfo::getRegisterNumbering(MO.getReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MO.isImm())
|
assert(MO.isImm() &&
|
||||||
return MO.getImm();
|
"Relocation required in an instruction that we cannot encode!");
|
||||||
|
return MO.getImm();
|
||||||
// FIXME.
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue