mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-10 02:25:47 +00:00
Convert the remaining instructions over, branches and calls. Fix a couple
minor bugs git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24762 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1,11 +1,10 @@
|
|||||||
|
|
||||||
Meta TODO list:
|
Meta TODO list:
|
||||||
1. Convert all instructions to use autogeneration for asm strings.
|
1. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing
|
||||||
2. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing
|
|
||||||
constant pool printing, etc.
|
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.
|
instructions.
|
||||||
4. profit!
|
3. profit!
|
||||||
|
|
||||||
|
|
||||||
SparcV8 backend skeleton
|
SparcV8 backend skeleton
|
||||||
|
@@ -70,7 +70,6 @@ namespace {
|
|||||||
void emitGlobalConstant(const Constant *CV);
|
void emitGlobalConstant(const Constant *CV);
|
||||||
void printConstantPool(MachineConstantPool *MCP);
|
void printConstantPool(MachineConstantPool *MCP);
|
||||||
void printOperand(const MachineInstr *MI, int opNum);
|
void printOperand(const MachineInstr *MI, int opNum);
|
||||||
void printMachineInstruction(const MachineInstr *MI);
|
|
||||||
bool printInstruction(const MachineInstr *MI); // autogenerated.
|
bool printInstruction(const MachineInstr *MI); // autogenerated.
|
||||||
bool runOnMachineFunction(MachineFunction &F);
|
bool runOnMachineFunction(MachineFunction &F);
|
||||||
bool doInitialization(Module &M);
|
bool doInitialization(Module &M);
|
||||||
@@ -357,7 +356,8 @@ bool SparcV8AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
|
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
|
||||||
II != E; ++II) {
|
II != E; ++II) {
|
||||||
// Print the assembly for the instruction.
|
// 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 << ")";
|
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<int> 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) {
|
bool SparcV8AsmPrinter::doInitialization(Module &M) {
|
||||||
Mang = new Mangler(M);
|
Mang = new Mangler(M);
|
||||||
return false; // success
|
return false; // success
|
||||||
|
@@ -32,13 +32,15 @@ class F2_1<bits<3> op2Val, dag ops, string asmstr> : F2 {
|
|||||||
let Inst{29-25} = rd;
|
let Inst{29-25} = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
class F2_2<bits<4> condVal, bits<3> op2Val, string name> : F2 {
|
class F2_2<bits<4> condVal, bits<3> op2Val, dag ops, string asmstr> : F2 {
|
||||||
bits<4> cond;
|
bits<4> cond;
|
||||||
bit annul = 0; // currently unused
|
bit annul = 0; // currently unused
|
||||||
|
|
||||||
|
dag OperandList = ops;
|
||||||
|
let AsmString = asmstr;
|
||||||
|
|
||||||
let cond = condVal;
|
let cond = condVal;
|
||||||
let op2 = op2Val;
|
let op2 = op2Val;
|
||||||
let Name = name;
|
|
||||||
|
|
||||||
let Inst{29} = annul;
|
let Inst{29} = annul;
|
||||||
let Inst{28-25} = cond;
|
let Inst{28-25} = cond;
|
||||||
|
@@ -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
|
// FIXME: should keep track of the fact that it defs the integer condition codes
|
||||||
let rd = 0 in
|
let rd = 0 in
|
||||||
def CMPri: F3_2<2, 0b010100,
|
def CMPri: F3_2<2, 0b010100,
|
||||||
(ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
|
(ops IntRegs:$b, i32imm:$c),
|
||||||
"cmp $b, $c, $dst">;
|
"cmp $b, $c">;
|
||||||
|
|
||||||
// Section B.1 - Load Integer Instructions, p. 90
|
// Section B.1 - Load Integer Instructions, p. 90
|
||||||
def LDSB: F3_2<3, 0b001001,
|
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
|
// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
|
||||||
|
|
||||||
// conditional branch class:
|
// conditional branch class:
|
||||||
class BranchV8<bits<4> cc, string nm> : F2_2<cc, 0b010, nm> {
|
class BranchV8<bits<4> cc, dag ops, string asmstr>
|
||||||
|
: F2_2<cc, 0b010, ops, asmstr> {
|
||||||
let isBranch = 1;
|
let isBranch = 1;
|
||||||
let isTerminator = 1;
|
let isTerminator = 1;
|
||||||
let hasDelaySlot = 1;
|
let hasDelaySlot = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let isBarrier = 1 in
|
let isBarrier = 1 in
|
||||||
def BA : BranchV8<0b1000, "ba">;
|
def BA : BranchV8<0b1000, (ops IntRegs:$dst), "ba $dst">;
|
||||||
def BN : BranchV8<0b0000, "bn">;
|
def BN : BranchV8<0b0000, (ops IntRegs:$dst), "bn $dst">;
|
||||||
def BNE : BranchV8<0b1001, "bne">;
|
def BNE : BranchV8<0b1001, (ops IntRegs:$dst), "bne $dst">;
|
||||||
def BE : BranchV8<0b0001, "be">;
|
def BE : BranchV8<0b0001, (ops IntRegs:$dst), "be $dst">;
|
||||||
def BG : BranchV8<0b1010, "bg">;
|
def BG : BranchV8<0b1010, (ops IntRegs:$dst), "bg $dst">;
|
||||||
def BLE : BranchV8<0b0010, "ble">;
|
def BLE : BranchV8<0b0010, (ops IntRegs:$dst), "ble $dst">;
|
||||||
def BGE : BranchV8<0b1011, "bge">;
|
def BGE : BranchV8<0b1011, (ops IntRegs:$dst), "bge $dst">;
|
||||||
def BL : BranchV8<0b0011, "bl">;
|
def BL : BranchV8<0b0011, (ops IntRegs:$dst), "bl $dst">;
|
||||||
def BGU : BranchV8<0b1100, "bgu">;
|
def BGU : BranchV8<0b1100, (ops IntRegs:$dst), "bgu $dst">;
|
||||||
def BLEU : BranchV8<0b0100, "bleu">;
|
def BLEU : BranchV8<0b0100, (ops IntRegs:$dst), "bleu $dst">;
|
||||||
def BCC : BranchV8<0b1101, "bcc">;
|
def BCC : BranchV8<0b1101, (ops IntRegs:$dst), "bcc $dst">;
|
||||||
def BCS : BranchV8<0b0101, "bcs">;
|
def BCS : BranchV8<0b0101, (ops IntRegs:$dst), "bcs $dst">;
|
||||||
|
|
||||||
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
|
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
|
||||||
|
|
||||||
// floating-point conditional branch class:
|
// floating-point conditional branch class:
|
||||||
class FPBranchV8<bits<4> cc, string nm> : F2_2<cc, 0b110, nm> {
|
class FPBranchV8<bits<4> cc, dag ops, string asmstr>
|
||||||
|
: F2_2<cc, 0b110, ops, asmstr> {
|
||||||
let isBranch = 1;
|
let isBranch = 1;
|
||||||
let isTerminator = 1;
|
let isTerminator = 1;
|
||||||
let hasDelaySlot = 1;
|
let hasDelaySlot = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
def FBA : FPBranchV8<0b1000, "fba">;
|
def FBA : FPBranchV8<0b1000, (ops IntRegs:$dst), "fba $dst">;
|
||||||
def FBN : FPBranchV8<0b0000, "fbn">;
|
def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst), "fbn $dst">;
|
||||||
def FBU : FPBranchV8<0b0111, "fbu">;
|
def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst), "fbu $dst">;
|
||||||
def FBG : FPBranchV8<0b0110, "fbg">;
|
def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst), "fbg $dst">;
|
||||||
def FBUG : FPBranchV8<0b0101, "fbug">;
|
def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst), "fbug $dst">;
|
||||||
def FBL : FPBranchV8<0b0100, "fbl">;
|
def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst), "fbl $dst">;
|
||||||
def FBUL : FPBranchV8<0b0011, "fbul">;
|
def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst), "fbul $dst">;
|
||||||
def FBLG : FPBranchV8<0b0010, "fblg">;
|
def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst), "fblg $dst">;
|
||||||
def FBNE : FPBranchV8<0b0001, "fbne">;
|
def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst), "fbne $dst">;
|
||||||
def FBE : FPBranchV8<0b1001, "fbe">;
|
def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst), "fbe $dst">;
|
||||||
def FBUE : FPBranchV8<0b1010, "fbue">;
|
def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst), "fbue $dst">;
|
||||||
def FBGE : FPBranchV8<0b1011, "fbge">;
|
def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst), "fbge $dst">;
|
||||||
def FBUGE: FPBranchV8<0b1100, "fbuge">;
|
def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst), "fbuge $dst">;
|
||||||
def FBLE : FPBranchV8<0b1101, "fble">;
|
def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst), "fble $dst">;
|
||||||
def FBULE: FPBranchV8<0b1110, "fbule">;
|
def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst), "fbule $dst">;
|
||||||
def FBO : FPBranchV8<0b1111, "fbo">;
|
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,
|
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
|
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
|
||||||
def CALL : InstV8 {
|
def CALL : InstV8 {
|
||||||
|
let OperandList = (ops IntRegs:$dst);
|
||||||
bits<30> disp;
|
bits<30> disp;
|
||||||
let op = 1;
|
let op = 1;
|
||||||
let Inst{29-0} = disp;
|
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
|
// 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.
|
// is modelled with a forced noop after the instruction.
|
||||||
def FCMPS : F3_3<2, 0b110101, 0b001010001,
|
def FCMPS : F3_3<2, 0b110101, 0b001010001,
|
||||||
(ops FPRegs:$src1, FPRegs:$src2),
|
(ops FPRegs:$src1, FPRegs:$src2),
|
||||||
"fcmps $src1, $src2\n nop">;
|
"fcmps $src1, $src2\n\tnop">;
|
||||||
def FCMPD : F3_3<2, 0b110101, 0b001010010,
|
def FCMPD : F3_3<2, 0b110101, 0b001010010,
|
||||||
(ops DFPRegs:$src1, DFPRegs:$src2),
|
(ops DFPRegs:$src1, DFPRegs:$src2),
|
||||||
"fcmpd $src1, $src2\n nop">;
|
"fcmpd $src1, $src2\n\tnop">;
|
||||||
def FCMPES : F3_3<2, 0b110101, 0b001010101,
|
def FCMPES : F3_3<2, 0b110101, 0b001010101,
|
||||||
(ops FPRegs:$src1, FPRegs:$src2),
|
(ops FPRegs:$src1, FPRegs:$src2),
|
||||||
"fcmpes $src1, $src2\n nop">;
|
"fcmpes $src1, $src2\n\tnop">;
|
||||||
def FCMPED : F3_3<2, 0b110101, 0b001010110,
|
def FCMPED : F3_3<2, 0b110101, 0b001010110,
|
||||||
(ops DFPRegs:$src1, DFPRegs:$src2),
|
(ops DFPRegs:$src1, DFPRegs:$src2),
|
||||||
"fcmped $src1, $src2\n nop">;
|
"fcmped $src1, $src2\n\tnop">;
|
||||||
|
@@ -1,11 +1,10 @@
|
|||||||
|
|
||||||
Meta TODO list:
|
Meta TODO list:
|
||||||
1. Convert all instructions to use autogeneration for asm strings.
|
1. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing
|
||||||
2. Convert asmprinter to use lib/CodeGen/AsmPrinter for global init printing
|
|
||||||
constant pool printing, etc.
|
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.
|
instructions.
|
||||||
4. profit!
|
3. profit!
|
||||||
|
|
||||||
|
|
||||||
SparcV8 backend skeleton
|
SparcV8 backend skeleton
|
||||||
|
@@ -70,7 +70,6 @@ namespace {
|
|||||||
void emitGlobalConstant(const Constant *CV);
|
void emitGlobalConstant(const Constant *CV);
|
||||||
void printConstantPool(MachineConstantPool *MCP);
|
void printConstantPool(MachineConstantPool *MCP);
|
||||||
void printOperand(const MachineInstr *MI, int opNum);
|
void printOperand(const MachineInstr *MI, int opNum);
|
||||||
void printMachineInstruction(const MachineInstr *MI);
|
|
||||||
bool printInstruction(const MachineInstr *MI); // autogenerated.
|
bool printInstruction(const MachineInstr *MI); // autogenerated.
|
||||||
bool runOnMachineFunction(MachineFunction &F);
|
bool runOnMachineFunction(MachineFunction &F);
|
||||||
bool doInitialization(Module &M);
|
bool doInitialization(Module &M);
|
||||||
@@ -357,7 +356,8 @@ bool SparcV8AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
|
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
|
||||||
II != E; ++II) {
|
II != E; ++II) {
|
||||||
// Print the assembly for the instruction.
|
// 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 << ")";
|
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<int> 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) {
|
bool SparcV8AsmPrinter::doInitialization(Module &M) {
|
||||||
Mang = new Mangler(M);
|
Mang = new Mangler(M);
|
||||||
return false; // success
|
return false; // success
|
||||||
|
@@ -32,13 +32,15 @@ class F2_1<bits<3> op2Val, dag ops, string asmstr> : F2 {
|
|||||||
let Inst{29-25} = rd;
|
let Inst{29-25} = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
class F2_2<bits<4> condVal, bits<3> op2Val, string name> : F2 {
|
class F2_2<bits<4> condVal, bits<3> op2Val, dag ops, string asmstr> : F2 {
|
||||||
bits<4> cond;
|
bits<4> cond;
|
||||||
bit annul = 0; // currently unused
|
bit annul = 0; // currently unused
|
||||||
|
|
||||||
|
dag OperandList = ops;
|
||||||
|
let AsmString = asmstr;
|
||||||
|
|
||||||
let cond = condVal;
|
let cond = condVal;
|
||||||
let op2 = op2Val;
|
let op2 = op2Val;
|
||||||
let Name = name;
|
|
||||||
|
|
||||||
let Inst{29} = annul;
|
let Inst{29} = annul;
|
||||||
let Inst{28-25} = cond;
|
let Inst{28-25} = cond;
|
||||||
|
@@ -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
|
// FIXME: should keep track of the fact that it defs the integer condition codes
|
||||||
let rd = 0 in
|
let rd = 0 in
|
||||||
def CMPri: F3_2<2, 0b010100,
|
def CMPri: F3_2<2, 0b010100,
|
||||||
(ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
|
(ops IntRegs:$b, i32imm:$c),
|
||||||
"cmp $b, $c, $dst">;
|
"cmp $b, $c">;
|
||||||
|
|
||||||
// Section B.1 - Load Integer Instructions, p. 90
|
// Section B.1 - Load Integer Instructions, p. 90
|
||||||
def LDSB: F3_2<3, 0b001001,
|
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
|
// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
|
||||||
|
|
||||||
// conditional branch class:
|
// conditional branch class:
|
||||||
class BranchV8<bits<4> cc, string nm> : F2_2<cc, 0b010, nm> {
|
class BranchV8<bits<4> cc, dag ops, string asmstr>
|
||||||
|
: F2_2<cc, 0b010, ops, asmstr> {
|
||||||
let isBranch = 1;
|
let isBranch = 1;
|
||||||
let isTerminator = 1;
|
let isTerminator = 1;
|
||||||
let hasDelaySlot = 1;
|
let hasDelaySlot = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let isBarrier = 1 in
|
let isBarrier = 1 in
|
||||||
def BA : BranchV8<0b1000, "ba">;
|
def BA : BranchV8<0b1000, (ops IntRegs:$dst), "ba $dst">;
|
||||||
def BN : BranchV8<0b0000, "bn">;
|
def BN : BranchV8<0b0000, (ops IntRegs:$dst), "bn $dst">;
|
||||||
def BNE : BranchV8<0b1001, "bne">;
|
def BNE : BranchV8<0b1001, (ops IntRegs:$dst), "bne $dst">;
|
||||||
def BE : BranchV8<0b0001, "be">;
|
def BE : BranchV8<0b0001, (ops IntRegs:$dst), "be $dst">;
|
||||||
def BG : BranchV8<0b1010, "bg">;
|
def BG : BranchV8<0b1010, (ops IntRegs:$dst), "bg $dst">;
|
||||||
def BLE : BranchV8<0b0010, "ble">;
|
def BLE : BranchV8<0b0010, (ops IntRegs:$dst), "ble $dst">;
|
||||||
def BGE : BranchV8<0b1011, "bge">;
|
def BGE : BranchV8<0b1011, (ops IntRegs:$dst), "bge $dst">;
|
||||||
def BL : BranchV8<0b0011, "bl">;
|
def BL : BranchV8<0b0011, (ops IntRegs:$dst), "bl $dst">;
|
||||||
def BGU : BranchV8<0b1100, "bgu">;
|
def BGU : BranchV8<0b1100, (ops IntRegs:$dst), "bgu $dst">;
|
||||||
def BLEU : BranchV8<0b0100, "bleu">;
|
def BLEU : BranchV8<0b0100, (ops IntRegs:$dst), "bleu $dst">;
|
||||||
def BCC : BranchV8<0b1101, "bcc">;
|
def BCC : BranchV8<0b1101, (ops IntRegs:$dst), "bcc $dst">;
|
||||||
def BCS : BranchV8<0b0101, "bcs">;
|
def BCS : BranchV8<0b0101, (ops IntRegs:$dst), "bcs $dst">;
|
||||||
|
|
||||||
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
|
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
|
||||||
|
|
||||||
// floating-point conditional branch class:
|
// floating-point conditional branch class:
|
||||||
class FPBranchV8<bits<4> cc, string nm> : F2_2<cc, 0b110, nm> {
|
class FPBranchV8<bits<4> cc, dag ops, string asmstr>
|
||||||
|
: F2_2<cc, 0b110, ops, asmstr> {
|
||||||
let isBranch = 1;
|
let isBranch = 1;
|
||||||
let isTerminator = 1;
|
let isTerminator = 1;
|
||||||
let hasDelaySlot = 1;
|
let hasDelaySlot = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
def FBA : FPBranchV8<0b1000, "fba">;
|
def FBA : FPBranchV8<0b1000, (ops IntRegs:$dst), "fba $dst">;
|
||||||
def FBN : FPBranchV8<0b0000, "fbn">;
|
def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst), "fbn $dst">;
|
||||||
def FBU : FPBranchV8<0b0111, "fbu">;
|
def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst), "fbu $dst">;
|
||||||
def FBG : FPBranchV8<0b0110, "fbg">;
|
def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst), "fbg $dst">;
|
||||||
def FBUG : FPBranchV8<0b0101, "fbug">;
|
def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst), "fbug $dst">;
|
||||||
def FBL : FPBranchV8<0b0100, "fbl">;
|
def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst), "fbl $dst">;
|
||||||
def FBUL : FPBranchV8<0b0011, "fbul">;
|
def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst), "fbul $dst">;
|
||||||
def FBLG : FPBranchV8<0b0010, "fblg">;
|
def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst), "fblg $dst">;
|
||||||
def FBNE : FPBranchV8<0b0001, "fbne">;
|
def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst), "fbne $dst">;
|
||||||
def FBE : FPBranchV8<0b1001, "fbe">;
|
def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst), "fbe $dst">;
|
||||||
def FBUE : FPBranchV8<0b1010, "fbue">;
|
def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst), "fbue $dst">;
|
||||||
def FBGE : FPBranchV8<0b1011, "fbge">;
|
def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst), "fbge $dst">;
|
||||||
def FBUGE: FPBranchV8<0b1100, "fbuge">;
|
def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst), "fbuge $dst">;
|
||||||
def FBLE : FPBranchV8<0b1101, "fble">;
|
def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst), "fble $dst">;
|
||||||
def FBULE: FPBranchV8<0b1110, "fbule">;
|
def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst), "fbule $dst">;
|
||||||
def FBO : FPBranchV8<0b1111, "fbo">;
|
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,
|
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
|
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
|
||||||
def CALL : InstV8 {
|
def CALL : InstV8 {
|
||||||
|
let OperandList = (ops IntRegs:$dst);
|
||||||
bits<30> disp;
|
bits<30> disp;
|
||||||
let op = 1;
|
let op = 1;
|
||||||
let Inst{29-0} = disp;
|
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
|
// 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.
|
// is modelled with a forced noop after the instruction.
|
||||||
def FCMPS : F3_3<2, 0b110101, 0b001010001,
|
def FCMPS : F3_3<2, 0b110101, 0b001010001,
|
||||||
(ops FPRegs:$src1, FPRegs:$src2),
|
(ops FPRegs:$src1, FPRegs:$src2),
|
||||||
"fcmps $src1, $src2\n nop">;
|
"fcmps $src1, $src2\n\tnop">;
|
||||||
def FCMPD : F3_3<2, 0b110101, 0b001010010,
|
def FCMPD : F3_3<2, 0b110101, 0b001010010,
|
||||||
(ops DFPRegs:$src1, DFPRegs:$src2),
|
(ops DFPRegs:$src1, DFPRegs:$src2),
|
||||||
"fcmpd $src1, $src2\n nop">;
|
"fcmpd $src1, $src2\n\tnop">;
|
||||||
def FCMPES : F3_3<2, 0b110101, 0b001010101,
|
def FCMPES : F3_3<2, 0b110101, 0b001010101,
|
||||||
(ops FPRegs:$src1, FPRegs:$src2),
|
(ops FPRegs:$src1, FPRegs:$src2),
|
||||||
"fcmpes $src1, $src2\n nop">;
|
"fcmpes $src1, $src2\n\tnop">;
|
||||||
def FCMPED : F3_3<2, 0b110101, 0b001010110,
|
def FCMPED : F3_3<2, 0b110101, 0b001010110,
|
||||||
(ops DFPRegs:$src1, DFPRegs:$src2),
|
(ops DFPRegs:$src1, DFPRegs:$src2),
|
||||||
"fcmped $src1, $src2\n nop">;
|
"fcmped $src1, $src2\n\tnop">;
|
||||||
|
Reference in New Issue
Block a user