MVT::ValueType VT) {
O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
}
+ void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
+ MVT::ValueType VT) {
+ printOp(MI->getOperand(OpNo));
+ }
+ void printPICLabel(const MachineInstr *MI, unsigned OpNo,
+ MVT::ValueType VT) {
+ // FIXME: should probably be converted to cout.width and cout.fill
+ O << "\"L0000" << LabelNumber << "$pb\"\n";
+ O << "\"L0000" << LabelNumber << "$pb\":";
+ }
void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
assert(((Desc.TSFlags & PPCII::PPC64) == 0) &&
"Instruction requires 64 bit support");
- // CALLpcrel and CALLindirect are handled specially here to print only the
- // appropriate number of args that the assembler expects. This is because
- // may have many arguments appended to record the uses of registers that are
- // holding arguments to the called function.
- if (Opcode == PPC::COND_BRANCH) {
- std::cerr << "Error: untranslated conditional branch psuedo instruction!\n";
- abort();
- } else if (Opcode == PPC::IMPLICIT_DEF) {
- --EmittedInsts; // Not an actual machine instruction
- O << "; IMPLICIT DEF ";
- printOp(MI->getOperand(0));
- O << "\n";
- return;
- } else if (Opcode == PPC::CALLpcrel) {
- O << TII.getName(Opcode) << " ";
- printOp(MI->getOperand(0));
- O << "\n";
- return;
- } else if (Opcode == PPC::CALLindirect) {
- O << TII.getName(Opcode) << " ";
- printImmOp(MI->getOperand(0), ArgType[0]);
- O << ", ";
- printImmOp(MI->getOperand(1), ArgType[0]);
- O << "\n";
- return;
- } else if (Opcode == PPC::MovePCtoLR) {
- ++EmittedInsts; // Actually two machine instructions
- // FIXME: should probably be converted to cout.width and cout.fill
- O << "bl \"L0000" << LabelNumber << "$pb\"\n";
- O << "\"L0000" << LabelNumber << "$pb\":\n";
- O << "\tmflr ";
- printOp(MI->getOperand(0));
- O << "\n";
- return;
- }
-
O << TII.getName(Opcode) << " ";
if (Opcode == PPC::LOADHiAddr) {
printOp(MI->getOperand(0));
MachineBasicBlock &FirstMBB = F->front();
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
GlobalBaseReg = makeAnotherReg(Type::IntTy);
- BuildMI(FirstMBB, MBBI, PPC::IMPLICIT_DEF, 0, PPC::LR);
- BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, GlobalBaseReg);
+ BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
+ BuildMI(FirstMBB, MBBI, PPC::MFLR, 0, GlobalBaseReg).addReg(PPC::LR);
GlobalBaseInitialized = true;
}
// Emit our copy of GlobalBaseReg to the destination register in the
MVT::ValueType VT) {
O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
}
+ void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
+ MVT::ValueType VT) {
+ printOp(MI->getOperand(OpNo));
+ }
+ void printPICLabel(const MachineInstr *MI, unsigned OpNo,
+ MVT::ValueType VT) {
+ // FIXME: should probably be converted to cout.width and cout.fill
+ O << "\"L0000" << LabelNumber << "$pb\"\n";
+ O << "\"L0000" << LabelNumber << "$pb\":";
+ }
void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
assert(((Desc.TSFlags & PPCII::PPC64) == 0) &&
"Instruction requires 64 bit support");
- // CALLpcrel and CALLindirect are handled specially here to print only the
- // appropriate number of args that the assembler expects. This is because
- // may have many arguments appended to record the uses of registers that are
- // holding arguments to the called function.
- if (Opcode == PPC::COND_BRANCH) {
- std::cerr << "Error: untranslated conditional branch psuedo instruction!\n";
- abort();
- } else if (Opcode == PPC::IMPLICIT_DEF) {
- --EmittedInsts; // Not an actual machine instruction
- O << "; IMPLICIT DEF ";
- printOp(MI->getOperand(0));
- O << "\n";
- return;
- } else if (Opcode == PPC::CALLpcrel) {
- O << TII.getName(Opcode) << " ";
- printOp(MI->getOperand(0));
- O << "\n";
- return;
- } else if (Opcode == PPC::CALLindirect) {
- O << TII.getName(Opcode) << " ";
- printImmOp(MI->getOperand(0), ArgType[0]);
- O << ", ";
- printImmOp(MI->getOperand(1), ArgType[0]);
- O << "\n";
- return;
- } else if (Opcode == PPC::MovePCtoLR) {
- ++EmittedInsts; // Actually two machine instructions
- // FIXME: should probably be converted to cout.width and cout.fill
- O << "bl \"L0000" << LabelNumber << "$pb\"\n";
- O << "\"L0000" << LabelNumber << "$pb\":\n";
- O << "\tmflr ";
- printOp(MI->getOperand(0));
- O << "\n";
- return;
- }
-
O << TII.getName(Opcode) << " ";
if (Opcode == PPC::LOADHiAddr) {
printOp(MI->getOperand(0));
// minor pessimization that saves us from having to worry about
// keeping the offsets up to date later when we emit long branch glue.
return 12;
- case PPC::MovePCtoLR:
- // MovePCtoLR is actually a combination of a branch-and-link (bl)
- // followed by a move from link register to dest reg (mflr)
- return 8;
- break;
case PPC::IMPLICIT_DEF: // no asm emitted
return 0;
break;
}
// 1.7.1 I-Form
-class IForm<string name, bits<6> opcode, bit aa, bit lk, bit ppc64, bit vmx>
- : I<name, opcode, ppc64, vmx> {
+class IForm<bits<6> opcode, bit aa, bit lk, bit ppc64, bit vmx,
+ dag OL, string asmstr> : I<"", opcode, ppc64, vmx> {
field bits<24> LI;
let ArgCount = 1;
let Inst{6-29} = LI;
let Inst{30} = aa;
let Inst{31} = lk;
+ let OperandList = OL;
+ let AsmString = asmstr;
}
// 1.7.2 B-Form
let B = 0;
}
-class XForm_16<string name, bits<6> opcode, bits<10> xo, bit ppc64, bit vmx>
- : I<name, opcode, ppc64, vmx> {
+class XForm_16<bits<6> opcode, bits<10> xo, bit ppc64, bit vmx,
+ dag OL, string asmstr> : I<"", opcode, ppc64, vmx> {
field bits<3> BF;
field bits<1> L;
field bits<5> RA;
let Inst{16-20} = RB;
let Inst{21-30} = xo;
let Inst{31} = 0;
+ let OperandList = OL;
+ let AsmString = asmstr;
}
-class XForm_16_ext<string name, bits<6> opcode, bits<10> xo, bit ppc64, bit vmx>
- : XForm_16<name, opcode, xo, ppc64, vmx> {
+class XForm_16_ext<bits<6> opcode, bits<10> xo, bit ppc64, bit vmx,
+ dag OL, string asmstr>
+ : XForm_16<opcode, xo, ppc64, vmx, OL, asmstr> {
+ let ArgCount = 3;
+ let Arg1Type = Gpr.Value;
+ let Arg2Type = Gpr.Value;
+ let Arg3Type = 0;
let L = ppc64;
}
let Arg2Type = Imm5.Value;
}
-class XLForm_2<string name, bits<6> opcode, bits<10> xo, bit lk, bit ppc64,
- bit vmx> : I<name, opcode, ppc64, vmx> {
+class XLForm_2<bits<6> opcode, bits<10> xo, bit lk, bit ppc64, bit vmx,
+ dag OL, string asmstr> : I<"", opcode, ppc64, vmx> {
field bits<5> BO;
field bits<5> BI;
field bits<2> BH;
let Inst{19-20} = BH;
let Inst{21-30} = xo;
let Inst{31} = lk;
+ let OperandList = OL;
+ let AsmString = asmstr;
}
-class XLForm_2_ext<string name, bits<6> opcode, bits<10> xo, bits<5> bo,
- bits<5> bi, bit lk, bit ppc64, bit vmx>
- : XLForm_2<name, opcode, xo, lk, ppc64, vmx> {
+class XLForm_2_ext<bits<6> opcode, bits<10> xo, bits<5> bo,
+ bits<5> bi, bit lk, bit ppc64, bit vmx,
+ dag OL, string asmstr>
+ : XLForm_2<opcode, xo, lk, ppc64, vmx, OL, asmstr> {
let ArgCount = 0;
let Arg0Type = 0;
let Arg1Type = 0;
//===----------------------------------------------------------------------===//
-class Pseudo<string name> : I<name, 0, 0, 0> {
- let Name = name;
- let ArgCount = 0;
- let PPC64 = 0;
- let VMX = 0;
+class Pseudo<dag OL, string asmstr> : I<"", 0, 0, 0> {
+ let ArgCount = 0;
+ let PPC64 = 0;
+ let VMX = 0;
- let Arg0Type = Pseudo.Value;
- let Arg1Type = Pseudo.Value;
- let Arg2Type = Pseudo.Value;
- let Arg3Type = Pseudo.Value;
- let Arg4Type = 0;
+ let Arg0Type = Pseudo.Value;
+ let Arg1Type = Pseudo.Value;
+ let Arg2Type = Pseudo.Value;
+ let Arg3Type = Pseudo.Value;
+ let Arg4Type = 0;
- let Inst{31-0} = 0;
+ let Inst{31-0} = 0;
+ let OperandList = OL;
+ let AsmString = asmstr;
}
include "PowerPCInstrFormats.td"
let isTerminator = 1, isReturn = 1 in
- def BLR : XLForm_2_ext<"blr", 19, 16, 20, 31, 1, 0, 0>;
+ def BLR : XLForm_2_ext<19, 16, 20, 31, 1, 0, 0, (ops), "blr">;
def u5imm : Operand<i8> {
let PrintMethod = "printU5ImmOperand";
def u16imm : Operand<i16> {
let PrintMethod = "printU16ImmOperand";
}
+def target : Operand<i32> {
+ let PrintMethod = "printBranchOperand";
+}
+def piclabel: Operand<i32> {
+ let PrintMethod = "printPICLabel";
+}
// Pseudo-instructions:
-def PHI : Pseudo<"PHI">;
-def ADJCALLSTACKDOWN : Pseudo<"ADJCALLSTACKDOWN">;
-def ADJCALLSTACKUP : Pseudo<"ADJCALLSTACKUP">;
-let Defs = [LR] in
- def MovePCtoLR : Pseudo<"MovePCtoLR">;
-def IMPLICIT_DEF : Pseudo<"IMPLICIT_DEF">;
+def PHI : Pseudo<(ops), "; PHI">;
+def ADJCALLSTACKDOWN : Pseudo<(ops), "; ADJCALLSTACKDOWN">;
+def ADJCALLSTACKUP : Pseudo<(ops), "; ADJCALLSTACKUP">;
+def IMPLICIT_DEF : Pseudo<(ops), "; IMPLICIT_DEF">;
+def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label">;
let isBranch = 1, isTerminator = 1 in {
- def COND_BRANCH : Pseudo<"COND_BRANCH">;
- def B : IForm<"b", 18, 0, 0, 0, 0>;
+ def COND_BRANCH : Pseudo<(ops), "; COND_BRANCH">;
+ def B : IForm<18, 0, 0, 0, 0, (ops target:$func), "b $func">;
// FIXME: 4*CR# needs to be added to the BI field!
// This will only work for CR0 as it stands now
def BLT : BForm_ext<"blt", 16, 0, 0, 12, 0, 0, 0>;
LR,XER,CTR,
CR0,CR1,CR5,CR6,CR7] in {
// Convenient aliases for call instructions
- def CALLpcrel : IForm<"bl", 18, 0, 1, 0, 0>;
- def CALLindirect : XLForm_2_ext<"bctrl", 19, 528, 20, 31, 1, 0, 0>;
+ def CALLpcrel : IForm<18, 0, 1, 0, 0, (ops target:$func), "bl $func">;
+ def CALLindirect : XLForm_2_ext<19, 528, 20, 31, 1, 0, 0, (ops), "bctrl">;
}
def LA : DForm_2<"la", 14, 0, 0>;
def STD : DSForm_2<"std", 62, 0, 1, 0>;
def STDU : DSForm_2<"stdu", 62, 1, 1, 0>;
-def CMP : XForm_16<"cmp", 31, 0, 0, 0>;
-def CMPL : XForm_16<"cmpl", 31, 32, 0, 0>;
-def CMPW : XForm_16_ext<"cmpw", 31, 0, 0, 0>;
-def CMPD : XForm_16_ext<"cmpd", 31, 0, 1, 0>;
-def CMPLW : XForm_16_ext<"cmplw", 31, 32, 0, 0>;
-def CMPLD : XForm_16_ext<"cmpld", 31, 32, 1, 0>;
-
// D-Form instructions. Most instructions that perform an operation on a
// register and an immediate are of this type.
//
"extsh $rA, $rS">;
def EXTSW : XForm_11<31, 986, 0, 1, 0, (ops GPRC:$rA, GPRC:$rS),
"extsw $rA, $rS">;
+def CMP : XForm_16<31, 0, 0, 0,
+ (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB),
+ "cmp $crD, $long, $rA, $rB">;
+def CMPL : XForm_16<31, 32, 0, 0,
+ (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB),
+ "cmpl $crD, $long, $rA, $rB">;
+def CMPW : XForm_16_ext<31, 0, 0, 0,
+ (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
+ "cmpw $crD, $rA, $rB">;
+def CMPD : XForm_16_ext<31, 0, 1, 0,
+ (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
+ "cmpd $crD, $rA, $rB">;
+def CMPLW : XForm_16_ext<31, 32, 0, 0,
+ (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
+ "cmplw $crD, $rA, $rB">;
+def CMPLD : XForm_16_ext<31, 32, 1, 0,
+ (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
+ "cmpld $crD, $rA, $rB">;
def FCMPU : XForm_17<63, 0, 0, 0, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
"fcmpu $crD, $fA, $fB">;
def LFSX : XForm_25<31, 535, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index),