diff --git a/lib/Target/Sparc/README.txt b/lib/Target/Sparc/README.txt index 1250207a3c3..5f9f85f814d 100644 --- a/lib/Target/Sparc/README.txt +++ b/lib/Target/Sparc/README.txt @@ -1,11 +1,10 @@ Meta TODO list: -1. Convert all instructions to use autogeneration for asm strings. -2. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing +1. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing constant pool printing, etc. -3. Create a new DAG -> DAG instruction selector, by adding patterns to the +2. Create a new DAG -> DAG instruction selector, by adding patterns to the instructions. -4. profit! +3. profit! SparcV8 backend skeleton diff --git a/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp index c983d5f8941..a21f4993589 100644 --- a/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -70,7 +70,6 @@ namespace { void emitGlobalConstant(const Constant *CV); void printConstantPool(MachineConstantPool *MCP); void printOperand(const MachineInstr *MI, int opNum); - void printMachineInstruction(const MachineInstr *MI); bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -357,7 +356,8 @@ bool SparcV8AsmPrinter::runOnMachineFunction(MachineFunction &MF) { for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. - printMachineInstruction(II); + O << "\t"; + printInstruction(II); } } @@ -421,42 +421,6 @@ void SparcV8AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { if (CloseParen) O << ")"; } -/// printMachineInstruction -- Print out a single SparcV8 LLVM instruction -/// MI in GAS syntax to the current output stream. -/// -void SparcV8AsmPrinter::printMachineInstruction(const MachineInstr *MI) { - O << "\t"; - if (printInstruction(MI)) return; - - unsigned Opcode = MI->getOpcode(); - const TargetInstrInfo &TII = *TM.getInstrInfo(); - const TargetInstrDescriptor &Desc = TII.get(Opcode); - - O << Desc.Name << " "; - - // print non-immediate, non-register-def operands - // then print immediate operands - // then print register-def operands. - std::vector print_order; - for (unsigned i = 0; i < MI->getNumOperands (); ++i) - if (!(MI->getOperand (i).isImmediate () - || (MI->getOperand (i).isRegister () - && MI->getOperand (i).isDef ()))) - print_order.push_back (i); - for (unsigned i = 0; i < MI->getNumOperands (); ++i) - if (MI->getOperand (i).isImmediate ()) - print_order.push_back (i); - for (unsigned i = 0; i < MI->getNumOperands (); ++i) - if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ()) - print_order.push_back (i); - for (unsigned i = 0, e = print_order.size (); i != e; ++i) { - printOperand (MI, print_order[i]); - if (i != (print_order.size () - 1)) - O << ", "; - } - O << "\n"; -} - bool SparcV8AsmPrinter::doInitialization(Module &M) { Mang = new Mangler(M); return false; // success diff --git a/lib/Target/Sparc/SparcInstrFormats.td b/lib/Target/Sparc/SparcInstrFormats.td index 4961d23063e..1fc1436eb78 100644 --- a/lib/Target/Sparc/SparcInstrFormats.td +++ b/lib/Target/Sparc/SparcInstrFormats.td @@ -32,13 +32,15 @@ class F2_1 op2Val, dag ops, string asmstr> : F2 { let Inst{29-25} = rd; } -class F2_2 condVal, bits<3> op2Val, string name> : F2 { +class F2_2 condVal, bits<3> op2Val, dag ops, string asmstr> : F2 { bits<4> cond; bit annul = 0; // currently unused + dag OperandList = ops; + let AsmString = asmstr; + let cond = condVal; let op2 = op2Val; - let Name = name; let Inst{29} = annul; let Inst{28-25} = cond; diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index becbaad8b5d..9f5d3f72bf8 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -65,8 +65,8 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in { // FIXME: should keep track of the fact that it defs the integer condition codes let rd = 0 in def CMPri: F3_2<2, 0b010100, - (ops IntRegs:$dst, IntRegs:$b, i32imm:$c), - "cmp $b, $c, $dst">; + (ops IntRegs:$b, i32imm:$c), + "cmp $b, $c">; // Section B.1 - Load Integer Instructions, p. 90 def LDSB: F3_2<3, 0b001001, @@ -373,51 +373,53 @@ def RESTOREri : F3_2<2, 0b111101, // Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 // conditional branch class: -class BranchV8 cc, string nm> : F2_2 { +class BranchV8 cc, dag ops, string asmstr> + : F2_2 { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; } let isBarrier = 1 in - def BA : BranchV8<0b1000, "ba">; -def BN : BranchV8<0b0000, "bn">; -def BNE : BranchV8<0b1001, "bne">; -def BE : BranchV8<0b0001, "be">; -def BG : BranchV8<0b1010, "bg">; -def BLE : BranchV8<0b0010, "ble">; -def BGE : BranchV8<0b1011, "bge">; -def BL : BranchV8<0b0011, "bl">; -def BGU : BranchV8<0b1100, "bgu">; -def BLEU : BranchV8<0b0100, "bleu">; -def BCC : BranchV8<0b1101, "bcc">; -def BCS : BranchV8<0b0101, "bcs">; + def BA : BranchV8<0b1000, (ops IntRegs:$dst), "ba $dst">; +def BN : BranchV8<0b0000, (ops IntRegs:$dst), "bn $dst">; +def BNE : BranchV8<0b1001, (ops IntRegs:$dst), "bne $dst">; +def BE : BranchV8<0b0001, (ops IntRegs:$dst), "be $dst">; +def BG : BranchV8<0b1010, (ops IntRegs:$dst), "bg $dst">; +def BLE : BranchV8<0b0010, (ops IntRegs:$dst), "ble $dst">; +def BGE : BranchV8<0b1011, (ops IntRegs:$dst), "bge $dst">; +def BL : BranchV8<0b0011, (ops IntRegs:$dst), "bl $dst">; +def BGU : BranchV8<0b1100, (ops IntRegs:$dst), "bgu $dst">; +def BLEU : BranchV8<0b0100, (ops IntRegs:$dst), "bleu $dst">; +def BCC : BranchV8<0b1101, (ops IntRegs:$dst), "bcc $dst">; +def BCS : BranchV8<0b0101, (ops IntRegs:$dst), "bcs $dst">; // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 // floating-point conditional branch class: -class FPBranchV8 cc, string nm> : F2_2 { +class FPBranchV8 cc, dag ops, string asmstr> + : F2_2 { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; } -def FBA : FPBranchV8<0b1000, "fba">; -def FBN : FPBranchV8<0b0000, "fbn">; -def FBU : FPBranchV8<0b0111, "fbu">; -def FBG : FPBranchV8<0b0110, "fbg">; -def FBUG : FPBranchV8<0b0101, "fbug">; -def FBL : FPBranchV8<0b0100, "fbl">; -def FBUL : FPBranchV8<0b0011, "fbul">; -def FBLG : FPBranchV8<0b0010, "fblg">; -def FBNE : FPBranchV8<0b0001, "fbne">; -def FBE : FPBranchV8<0b1001, "fbe">; -def FBUE : FPBranchV8<0b1010, "fbue">; -def FBGE : FPBranchV8<0b1011, "fbge">; -def FBUGE: FPBranchV8<0b1100, "fbuge">; -def FBLE : FPBranchV8<0b1101, "fble">; -def FBULE: FPBranchV8<0b1110, "fbule">; -def FBO : FPBranchV8<0b1111, "fbo">; +def FBA : FPBranchV8<0b1000, (ops IntRegs:$dst), "fba $dst">; +def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst), "fbn $dst">; +def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst), "fbu $dst">; +def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst), "fbg $dst">; +def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst), "fbug $dst">; +def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst), "fbl $dst">; +def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst), "fbul $dst">; +def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst), "fblg $dst">; +def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst), "fbne $dst">; +def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst), "fbe $dst">; +def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst), "fbue $dst">; +def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst), "fbge $dst">; +def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst), "fbuge $dst">; +def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst), "fble $dst">; +def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst), "fbule $dst">; +def FBO : FPBranchV8<0b1111, (ops IntRegs:$dst), "fbo $dst">; @@ -428,10 +430,11 @@ let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1 in { let Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in def CALL : InstV8 { + let OperandList = (ops IntRegs:$dst); bits<30> disp; let op = 1; let Inst{29-0} = disp; - let Name = "call"; + let AsmString = "call $dst"; } // indirect call (O7 is an EXPLICIT def in indirect calls, so it cannot also @@ -524,13 +527,13 @@ def FDIVD : F3_3<2, 0b110100, 0b001001110, // is modelled with a forced noop after the instruction. def FCMPS : F3_3<2, 0b110101, 0b001010001, (ops FPRegs:$src1, FPRegs:$src2), - "fcmps $src1, $src2\n nop">; + "fcmps $src1, $src2\n\tnop">; def FCMPD : F3_3<2, 0b110101, 0b001010010, (ops DFPRegs:$src1, DFPRegs:$src2), - "fcmpd $src1, $src2\n nop">; + "fcmpd $src1, $src2\n\tnop">; def FCMPES : F3_3<2, 0b110101, 0b001010101, (ops FPRegs:$src1, FPRegs:$src2), - "fcmpes $src1, $src2\n nop">; + "fcmpes $src1, $src2\n\tnop">; def FCMPED : F3_3<2, 0b110101, 0b001010110, (ops DFPRegs:$src1, DFPRegs:$src2), - "fcmped $src1, $src2\n nop">; + "fcmped $src1, $src2\n\tnop">; diff --git a/lib/Target/SparcV8/README.txt b/lib/Target/SparcV8/README.txt index 1250207a3c3..5f9f85f814d 100644 --- a/lib/Target/SparcV8/README.txt +++ b/lib/Target/SparcV8/README.txt @@ -1,11 +1,10 @@ Meta TODO list: -1. Convert all instructions to use autogeneration for asm strings. -2. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing +1. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing constant pool printing, etc. -3. Create a new DAG -> DAG instruction selector, by adding patterns to the +2. Create a new DAG -> DAG instruction selector, by adding patterns to the instructions. -4. profit! +3. profit! SparcV8 backend skeleton diff --git a/lib/Target/SparcV8/SparcV8AsmPrinter.cpp b/lib/Target/SparcV8/SparcV8AsmPrinter.cpp index c983d5f8941..a21f4993589 100644 --- a/lib/Target/SparcV8/SparcV8AsmPrinter.cpp +++ b/lib/Target/SparcV8/SparcV8AsmPrinter.cpp @@ -70,7 +70,6 @@ namespace { void emitGlobalConstant(const Constant *CV); void printConstantPool(MachineConstantPool *MCP); void printOperand(const MachineInstr *MI, int opNum); - void printMachineInstruction(const MachineInstr *MI); bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -357,7 +356,8 @@ bool SparcV8AsmPrinter::runOnMachineFunction(MachineFunction &MF) { for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. - printMachineInstruction(II); + O << "\t"; + printInstruction(II); } } @@ -421,42 +421,6 @@ void SparcV8AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { if (CloseParen) O << ")"; } -/// printMachineInstruction -- Print out a single SparcV8 LLVM instruction -/// MI in GAS syntax to the current output stream. -/// -void SparcV8AsmPrinter::printMachineInstruction(const MachineInstr *MI) { - O << "\t"; - if (printInstruction(MI)) return; - - unsigned Opcode = MI->getOpcode(); - const TargetInstrInfo &TII = *TM.getInstrInfo(); - const TargetInstrDescriptor &Desc = TII.get(Opcode); - - O << Desc.Name << " "; - - // print non-immediate, non-register-def operands - // then print immediate operands - // then print register-def operands. - std::vector print_order; - for (unsigned i = 0; i < MI->getNumOperands (); ++i) - if (!(MI->getOperand (i).isImmediate () - || (MI->getOperand (i).isRegister () - && MI->getOperand (i).isDef ()))) - print_order.push_back (i); - for (unsigned i = 0; i < MI->getNumOperands (); ++i) - if (MI->getOperand (i).isImmediate ()) - print_order.push_back (i); - for (unsigned i = 0; i < MI->getNumOperands (); ++i) - if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ()) - print_order.push_back (i); - for (unsigned i = 0, e = print_order.size (); i != e; ++i) { - printOperand (MI, print_order[i]); - if (i != (print_order.size () - 1)) - O << ", "; - } - O << "\n"; -} - bool SparcV8AsmPrinter::doInitialization(Module &M) { Mang = new Mangler(M); return false; // success diff --git a/lib/Target/SparcV8/SparcV8InstrFormats.td b/lib/Target/SparcV8/SparcV8InstrFormats.td index 4961d23063e..1fc1436eb78 100644 --- a/lib/Target/SparcV8/SparcV8InstrFormats.td +++ b/lib/Target/SparcV8/SparcV8InstrFormats.td @@ -32,13 +32,15 @@ class F2_1 op2Val, dag ops, string asmstr> : F2 { let Inst{29-25} = rd; } -class F2_2 condVal, bits<3> op2Val, string name> : F2 { +class F2_2 condVal, bits<3> op2Val, dag ops, string asmstr> : F2 { bits<4> cond; bit annul = 0; // currently unused + dag OperandList = ops; + let AsmString = asmstr; + let cond = condVal; let op2 = op2Val; - let Name = name; let Inst{29} = annul; let Inst{28-25} = cond; diff --git a/lib/Target/SparcV8/SparcV8InstrInfo.td b/lib/Target/SparcV8/SparcV8InstrInfo.td index becbaad8b5d..9f5d3f72bf8 100644 --- a/lib/Target/SparcV8/SparcV8InstrInfo.td +++ b/lib/Target/SparcV8/SparcV8InstrInfo.td @@ -65,8 +65,8 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in { // FIXME: should keep track of the fact that it defs the integer condition codes let rd = 0 in def CMPri: F3_2<2, 0b010100, - (ops IntRegs:$dst, IntRegs:$b, i32imm:$c), - "cmp $b, $c, $dst">; + (ops IntRegs:$b, i32imm:$c), + "cmp $b, $c">; // Section B.1 - Load Integer Instructions, p. 90 def LDSB: F3_2<3, 0b001001, @@ -373,51 +373,53 @@ def RESTOREri : F3_2<2, 0b111101, // Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 // conditional branch class: -class BranchV8 cc, string nm> : F2_2 { +class BranchV8 cc, dag ops, string asmstr> + : F2_2 { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; } let isBarrier = 1 in - def BA : BranchV8<0b1000, "ba">; -def BN : BranchV8<0b0000, "bn">; -def BNE : BranchV8<0b1001, "bne">; -def BE : BranchV8<0b0001, "be">; -def BG : BranchV8<0b1010, "bg">; -def BLE : BranchV8<0b0010, "ble">; -def BGE : BranchV8<0b1011, "bge">; -def BL : BranchV8<0b0011, "bl">; -def BGU : BranchV8<0b1100, "bgu">; -def BLEU : BranchV8<0b0100, "bleu">; -def BCC : BranchV8<0b1101, "bcc">; -def BCS : BranchV8<0b0101, "bcs">; + def BA : BranchV8<0b1000, (ops IntRegs:$dst), "ba $dst">; +def BN : BranchV8<0b0000, (ops IntRegs:$dst), "bn $dst">; +def BNE : BranchV8<0b1001, (ops IntRegs:$dst), "bne $dst">; +def BE : BranchV8<0b0001, (ops IntRegs:$dst), "be $dst">; +def BG : BranchV8<0b1010, (ops IntRegs:$dst), "bg $dst">; +def BLE : BranchV8<0b0010, (ops IntRegs:$dst), "ble $dst">; +def BGE : BranchV8<0b1011, (ops IntRegs:$dst), "bge $dst">; +def BL : BranchV8<0b0011, (ops IntRegs:$dst), "bl $dst">; +def BGU : BranchV8<0b1100, (ops IntRegs:$dst), "bgu $dst">; +def BLEU : BranchV8<0b0100, (ops IntRegs:$dst), "bleu $dst">; +def BCC : BranchV8<0b1101, (ops IntRegs:$dst), "bcc $dst">; +def BCS : BranchV8<0b0101, (ops IntRegs:$dst), "bcs $dst">; // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 // floating-point conditional branch class: -class FPBranchV8 cc, string nm> : F2_2 { +class FPBranchV8 cc, dag ops, string asmstr> + : F2_2 { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; } -def FBA : FPBranchV8<0b1000, "fba">; -def FBN : FPBranchV8<0b0000, "fbn">; -def FBU : FPBranchV8<0b0111, "fbu">; -def FBG : FPBranchV8<0b0110, "fbg">; -def FBUG : FPBranchV8<0b0101, "fbug">; -def FBL : FPBranchV8<0b0100, "fbl">; -def FBUL : FPBranchV8<0b0011, "fbul">; -def FBLG : FPBranchV8<0b0010, "fblg">; -def FBNE : FPBranchV8<0b0001, "fbne">; -def FBE : FPBranchV8<0b1001, "fbe">; -def FBUE : FPBranchV8<0b1010, "fbue">; -def FBGE : FPBranchV8<0b1011, "fbge">; -def FBUGE: FPBranchV8<0b1100, "fbuge">; -def FBLE : FPBranchV8<0b1101, "fble">; -def FBULE: FPBranchV8<0b1110, "fbule">; -def FBO : FPBranchV8<0b1111, "fbo">; +def FBA : FPBranchV8<0b1000, (ops IntRegs:$dst), "fba $dst">; +def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst), "fbn $dst">; +def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst), "fbu $dst">; +def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst), "fbg $dst">; +def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst), "fbug $dst">; +def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst), "fbl $dst">; +def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst), "fbul $dst">; +def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst), "fblg $dst">; +def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst), "fbne $dst">; +def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst), "fbe $dst">; +def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst), "fbue $dst">; +def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst), "fbge $dst">; +def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst), "fbuge $dst">; +def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst), "fble $dst">; +def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst), "fbule $dst">; +def FBO : FPBranchV8<0b1111, (ops IntRegs:$dst), "fbo $dst">; @@ -428,10 +430,11 @@ let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1 in { let Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in def CALL : InstV8 { + let OperandList = (ops IntRegs:$dst); bits<30> disp; let op = 1; let Inst{29-0} = disp; - let Name = "call"; + let AsmString = "call $dst"; } // indirect call (O7 is an EXPLICIT def in indirect calls, so it cannot also @@ -524,13 +527,13 @@ def FDIVD : F3_3<2, 0b110100, 0b001001110, // is modelled with a forced noop after the instruction. def FCMPS : F3_3<2, 0b110101, 0b001010001, (ops FPRegs:$src1, FPRegs:$src2), - "fcmps $src1, $src2\n nop">; + "fcmps $src1, $src2\n\tnop">; def FCMPD : F3_3<2, 0b110101, 0b001010010, (ops DFPRegs:$src1, DFPRegs:$src2), - "fcmpd $src1, $src2\n nop">; + "fcmpd $src1, $src2\n\tnop">; def FCMPES : F3_3<2, 0b110101, 0b001010101, (ops FPRegs:$src1, FPRegs:$src2), - "fcmpes $src1, $src2\n nop">; + "fcmpes $src1, $src2\n\tnop">; def FCMPED : F3_3<2, 0b110101, 0b001010110, (ops DFPRegs:$src1, DFPRegs:$src2), - "fcmped $src1, $src2\n nop">; + "fcmped $src1, $src2\n\tnop">;