mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 11:35:51 -04:00
Fixed and completed bitshifts, fixed xor, added neg
This commit is contained in:
parent
6a892a4b93
commit
f229bdcee8
@ -272,6 +272,13 @@ static unsigned encodeArArpSttModOp(unsigned reg)
|
|||||||
switch (reg)
|
switch (reg)
|
||||||
{
|
{
|
||||||
case Teak::STT0: return 8;
|
case Teak::STT0: return 8;
|
||||||
|
case Teak::STT1: return 9;
|
||||||
|
case Teak::STT2: return 10;
|
||||||
|
//reserved
|
||||||
|
case Teak::MOD0: return 12;
|
||||||
|
case Teak::MOD1: return 13;
|
||||||
|
case Teak::MOD2: return 14;
|
||||||
|
case Teak::MOD3: return 15;
|
||||||
default:
|
default:
|
||||||
dbgs() << "encodeArArpSttModOp(" << reg << ")\n";
|
dbgs() << "encodeArArpSttModOp(" << reg << ")\n";
|
||||||
llvm_unreachable("Unsupported register");
|
llvm_unreachable("Unsupported register");
|
||||||
@ -279,6 +286,25 @@ static unsigned encodeArArpSttModOp(unsigned reg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned encodeSttModOp(unsigned reg)
|
||||||
|
{
|
||||||
|
switch(reg)
|
||||||
|
{
|
||||||
|
case Teak::STT0: return 0;
|
||||||
|
case Teak::STT1: return 1;
|
||||||
|
case Teak::STT2: return 2;
|
||||||
|
//reserved
|
||||||
|
case Teak::MOD0: return 4;
|
||||||
|
case Teak::MOD1: return 5;
|
||||||
|
case Teak::MOD2: return 6;
|
||||||
|
case Teak::MOD3: return 7;
|
||||||
|
default:
|
||||||
|
dbgs() << "encodeSttModOp(" << reg << ")\n";
|
||||||
|
llvm_unreachable("Unsupported register");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||||
SmallVectorImpl<MCFixup> &Fixups,
|
SmallVectorImpl<MCFixup> &Fixups,
|
||||||
const MCSubtargetInfo &STI) const
|
const MCSubtargetInfo &STI) const
|
||||||
@ -416,6 +442,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
unsigned dstReg = MI.getOperand(0).getReg();
|
unsigned dstReg = MI.getOperand(0).getReg();
|
||||||
if(MI.getOpcode() == Teak::MOV_regnobp016_abl)
|
if(MI.getOpcode() == Teak::MOV_regnobp016_abl)
|
||||||
dstReg = teakGetAbLReg(dstReg);
|
dstReg = teakGetAbLReg(dstReg);
|
||||||
|
if(TeakMCRegisterClasses[Teak::BRegsRegClassID].contains(dstReg))
|
||||||
|
EmitConstant(0x5EC0 | encodeRegisterP0Op(MI.getOperand(1).getReg()) | (encodeBxOp(dstReg) << 5), 2, OS);
|
||||||
|
else
|
||||||
EmitConstant(0x5800 | encodeRegisterP0Op(MI.getOperand(1).getReg()) | (encodeRegisterOp(dstReg) << 5), 2, OS);
|
EmitConstant(0x5800 | encodeRegisterP0Op(MI.getOperand(1).getReg()) | (encodeRegisterOp(dstReg) << 5), 2, OS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -475,6 +504,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
case Teak::MPY_y0_regnob16:
|
case Teak::MPY_y0_regnob16:
|
||||||
EmitConstant(0x8040 | encodeRegisterOp(MI.getOperand(2).getReg()), 2, OS);
|
EmitConstant(0x8040 | encodeRegisterOp(MI.getOperand(2).getReg()), 2, OS);
|
||||||
break;
|
break;
|
||||||
|
case Teak::NEG_a:
|
||||||
|
EmitConstant(0x6790 | (encodeAxOp(MI.getOperand(0).getReg()) << 12), 2, OS);
|
||||||
|
break;
|
||||||
case Teak::NOT_a:
|
case Teak::NOT_a:
|
||||||
EmitConstant(0x6780 | (encodeAxOp(MI.getOperand(0).getReg()) << 12), 2, OS);
|
EmitConstant(0x6780 | (encodeAxOp(MI.getOperand(0).getReg()) << 12), 2, OS);
|
||||||
break;
|
break;
|
||||||
@ -503,14 +535,52 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
EmitConstant(0xD4D8 | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
|
EmitConstant(0xD4D8 | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
|
||||||
EmitConstant(MI.getOperand(2).getImm() & 0xFFFF, 2, OS);
|
EmitConstant(MI.getOperand(2).getImm() & 0xFFFF, 2, OS);
|
||||||
break;
|
break;
|
||||||
//todo: these three should be pseudo ops
|
|
||||||
case Teak::SHFI_ab_ab:
|
case Teak::RST_imm16_regnob16:
|
||||||
case Teak::SHFI2_ab_ab:
|
case Teak::RST_imm16_abl:
|
||||||
case Teak::SHFI3_ab_ab:
|
{
|
||||||
|
unsigned aReg = MI.getOperand(0).getReg();
|
||||||
|
if(MI.getOpcode() == Teak::RST_imm16_abl)
|
||||||
|
aReg = teakGetAbLReg(aReg);
|
||||||
|
EmitConstant(0x83E0 | encodeRegisterOp(aReg), 2, OS);
|
||||||
|
EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Teak::RST_imm16_sttmod:
|
||||||
|
{
|
||||||
|
EmitConstant(0x4388 | encodeSttModOp(MI.getOperand(0).getReg()), 2, OS);
|
||||||
|
EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Teak::SET_imm16_regnob16:
|
||||||
|
case Teak::SET_imm16_abl:
|
||||||
|
{
|
||||||
|
unsigned aReg = MI.getOperand(0).getReg();
|
||||||
|
if(MI.getOpcode() == Teak::SET_imm16_abl)
|
||||||
|
aReg = teakGetAbLReg(aReg);
|
||||||
|
EmitConstant(0x81E0 | encodeRegisterOp(aReg), 2, OS);
|
||||||
|
EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Teak::SET_imm16_sttmod:
|
||||||
|
{
|
||||||
|
EmitConstant(0x43C8 | encodeSttModOp(MI.getOperand(0).getReg()), 2, OS);
|
||||||
|
EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Teak::SHFC_arith_ab_ab_sv:
|
||||||
|
EmitConstant(0xD280
|
||||||
|
| (encodeAbOp(MI.getOperand(1).getReg()) << 10)
|
||||||
|
| (encodeAbOp(MI.getOperand(0).getReg()) << 5), 2, OS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Teak::SHFI_arith_ab_ab:
|
||||||
EmitConstant(0x9240
|
EmitConstant(0x9240
|
||||||
| (encodeAbOp(MI.getOperand(1).getReg()) << 10)
|
| (encodeAbOp(MI.getOperand(1).getReg()) << 10)
|
||||||
| (encodeAbOp(MI.getOperand(0).getReg()) << 7)
|
| (encodeAbOp(MI.getOperand(0).getReg()) << 7)
|
||||||
| ((MI.getOperand(2).getImm() * (MI.getOpcode() == Teak::SHFI2_ab_ab ? 1 : -1)) & 0x7F), 2, OS);
|
| (MI.getOperand(2).getImm() & 0x3F), 2, OS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Teak::SUB_ab_ab:
|
case Teak::SUB_ab_ab:
|
||||||
@ -570,7 +640,7 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
EmitConstant(MI.getOperand(1).getImm(), 2, OS);
|
EmitConstant(MI.getOperand(1).getImm(), 2, OS);
|
||||||
break;
|
break;
|
||||||
case Teak::XOR_imm16_a:
|
case Teak::XOR_imm16_a:
|
||||||
EmitConstant(0xD4FA | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
|
EmitConstant(0x84C0 | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
|
||||||
EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
|
EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
|
||||||
break;
|
break;
|
||||||
case Teak::XOR_regnobp016_a:
|
case Teak::XOR_regnobp016_a:
|
||||||
|
@ -55,5 +55,5 @@ def CC_Teak : CallingConv<[
|
|||||||
//CCIfType<[i32], CCAssignToStack<4, 4>>
|
//CCIfType<[i32], CCAssignToStack<4, 4>>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
def CSR : CalleeSavedRegs<(add Y0, Y1, R0, R1, R2, R3, R4, R5, R6, R7, SV)>;
|
def CSR : CalleeSavedRegs<(add Y0, Y1, R0, R1, R2, R3, R4, R5, R6, R7)>;
|
||||||
def CSR_NoRegs : CalleeSavedRegs<(add)>;
|
def CSR_NoRegs : CalleeSavedRegs<(add)>;
|
@ -98,11 +98,15 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM)
|
|||||||
|
|
||||||
setOperationAction(ISD::ADD, MVT::i16, Custom);
|
setOperationAction(ISD::ADD, MVT::i16, Custom);
|
||||||
setOperationAction(ISD::AND, MVT::i16, Custom);
|
setOperationAction(ISD::AND, MVT::i16, Custom);
|
||||||
|
setOperationAction(ISD::XOR, MVT::i16, Custom);
|
||||||
setOperationAction(ISD::OR, MVT::i16, Custom);
|
setOperationAction(ISD::OR, MVT::i16, Custom);
|
||||||
setOperationAction(ISD::SUB, MVT::i16, Custom);
|
setOperationAction(ISD::SUB, MVT::i16, Custom);
|
||||||
setOperationAction(ISD::SHL, MVT::i16, Custom);
|
setOperationAction(ISD::SHL, MVT::i16, Custom);
|
||||||
|
setOperationAction(ISD::SHL, MVT::i40, Custom);
|
||||||
setOperationAction(ISD::SRL, MVT::i16, Custom);
|
setOperationAction(ISD::SRL, MVT::i16, Custom);
|
||||||
|
setOperationAction(ISD::SRL, MVT::i40, Custom);
|
||||||
setOperationAction(ISD::SRA, MVT::i16, Custom);
|
setOperationAction(ISD::SRA, MVT::i16, Custom);
|
||||||
|
setOperationAction(ISD::SRA, MVT::i40, Custom);
|
||||||
|
|
||||||
setStackPointerRegisterToSaveRestore(Teak::SP);
|
setStackPointerRegisterToSaveRestore(Teak::SP);
|
||||||
|
|
||||||
@ -343,6 +347,7 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
|||||||
case ISD::AND:
|
case ISD::AND:
|
||||||
case ISD::OR:
|
case ISD::OR:
|
||||||
case ISD::SUB:
|
case ISD::SUB:
|
||||||
|
case ISD::XOR:
|
||||||
{
|
{
|
||||||
const SDNode *N = Op.getNode();
|
const SDNode *N = Op.getNode();
|
||||||
SDLoc dl(N);
|
SDLoc dl(N);
|
||||||
@ -354,18 +359,97 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
|||||||
return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, NewWOp);//NewRes);
|
return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, NewWOp);//NewRes);
|
||||||
}
|
}
|
||||||
case ISD::SHL:
|
case ISD::SHL:
|
||||||
case ISD::SRL:
|
|
||||||
case ISD::SRA:
|
|
||||||
{
|
{
|
||||||
DAG.dump();
|
|
||||||
const SDNode *N = Op.getNode();
|
const SDNode *N = Op.getNode();
|
||||||
SDLoc dl(N);
|
SDLoc dl(N);
|
||||||
assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation");
|
if(N->getValueType(0) == MVT::i16)
|
||||||
SDValue NewOp0 = DAG.getNode(Op.getOpcode() == ISD::SRA ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, MVT::i40, N->getOperand(0));
|
{
|
||||||
SDValue NewWOp = DAG.getNode(N->getOpcode(), dl, MVT::i40, NewOp0, N->getOperand(1));
|
return
|
||||||
//SDValue NewRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i40, NewWOp, DAG.getValueType(MVT::i16));
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
|
||||||
return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, NewWOp);//NewRes);
|
DAG.getNode(TeakISD::SHIFT_ARITH, dl, MVT::i40,
|
||||||
|
DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i40,
|
||||||
|
N->getOperand(0)),
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, N->getOperand(1))));
|
||||||
}
|
}
|
||||||
|
else if(N->getValueType(0) == MVT::i40)
|
||||||
|
{
|
||||||
|
//emit arithmetic shift, because it is the same as logical for left
|
||||||
|
//shifts, and we don't want to modify the shift flag if not needed
|
||||||
|
return DAG.getNode(TeakISD::SHIFT_ARITH, dl, MVT::i40,
|
||||||
|
N->getOperand(0),
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, N->getOperand(1)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
llvm_unreachable("Unimplemented shift operand");
|
||||||
|
}
|
||||||
|
case ISD::SRL:
|
||||||
|
{
|
||||||
|
const SDNode* N = Op.getNode();
|
||||||
|
SDLoc dl(N);
|
||||||
|
SDValue shiftOp = N->getOperand(1);
|
||||||
|
if(N->getValueType(0) == MVT::i16)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
|
||||||
|
DAG.getNode(TeakISD::SHIFT_LOGIC, dl, MVT::i40,
|
||||||
|
DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i40,
|
||||||
|
N->getOperand(0)),
|
||||||
|
//negation for right shift
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
|
||||||
|
DAG.getNode(ISD::SUB, dl, MVT::i40,
|
||||||
|
DAG.getConstant(0, dl, MVT::i40), N->getOperand(1)))));
|
||||||
|
}
|
||||||
|
else if(N->getValueType(0) == MVT::i40)
|
||||||
|
return
|
||||||
|
DAG.getNode(TeakISD::SHIFT_LOGIC, dl, MVT::i40,
|
||||||
|
N->getOperand(0),
|
||||||
|
//negation for right shift
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
|
||||||
|
DAG.getNode(ISD::SUB, dl, MVT::i40,
|
||||||
|
DAG.getConstant(0, dl, MVT::i40), N->getOperand(1))));
|
||||||
|
else
|
||||||
|
llvm_unreachable("Unimplemented shift operand");
|
||||||
|
}
|
||||||
|
case ISD::SRA:
|
||||||
|
{
|
||||||
|
const SDNode *N = Op.getNode();
|
||||||
|
SDLoc dl(N);
|
||||||
|
if(N->getValueType(0) == MVT::i16)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
|
||||||
|
DAG.getNode(TeakISD::SHIFT_ARITH, dl, MVT::i40,
|
||||||
|
DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i40,
|
||||||
|
N->getOperand(0)),
|
||||||
|
//negation for right shift
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
|
||||||
|
DAG.getNode(ISD::SUB, dl, MVT::i40,
|
||||||
|
DAG.getConstant(0, dl, MVT::i40), N->getOperand(1)))));
|
||||||
|
}
|
||||||
|
else if(N->getValueType(0) == MVT::i40)
|
||||||
|
return
|
||||||
|
DAG.getNode(TeakISD::SHIFT_ARITH, dl, MVT::i40,
|
||||||
|
N->getOperand(0),
|
||||||
|
//negation for right shift
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
|
||||||
|
DAG.getNode(ISD::SUB, dl, MVT::i40,
|
||||||
|
DAG.getConstant(0, dl, MVT::i40), N->getOperand(1))));
|
||||||
|
else
|
||||||
|
llvm_unreachable("Unimplemented shift operand");
|
||||||
|
}
|
||||||
|
// case ISD::SHL:
|
||||||
|
// case ISD::SRL:
|
||||||
|
// case ISD::SRA:
|
||||||
|
// {
|
||||||
|
// DAG.dump();
|
||||||
|
// const SDNode *N = Op.getNode();
|
||||||
|
// SDLoc dl(N);
|
||||||
|
// assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation");
|
||||||
|
// SDValue NewOp0 = DAG.getNode(Op.getOpcode() == ISD::SRA ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, MVT::i40, N->getOperand(0));
|
||||||
|
// SDValue NewWOp = DAG.getNode(N->getOpcode(), dl, MVT::i40, NewOp0, N->getOperand(1));
|
||||||
|
// //SDValue NewRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i40, NewWOp, DAG.getValueType(MVT::i16));
|
||||||
|
// return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, NewWOp);//NewRes);
|
||||||
|
// }
|
||||||
// case ISD::MUL:
|
// case ISD::MUL:
|
||||||
// {
|
// {
|
||||||
// const SDNode *N = Op.getNode();
|
// const SDNode *N = Op.getNode();
|
||||||
|
@ -38,7 +38,9 @@ enum NodeType {
|
|||||||
CMPICC,
|
CMPICC,
|
||||||
BRICC,
|
BRICC,
|
||||||
SELECT_ICC,
|
SELECT_ICC,
|
||||||
WRAPPER
|
WRAPPER,
|
||||||
|
SHIFT_ARITH,
|
||||||
|
SHIFT_LOGIC
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
|
|||||||
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg)
|
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg)
|
||||||
.addReg(Teak::R7)
|
.addReg(Teak::R7)
|
||||||
.addImm(frameOffset);
|
.addImm(frameOffset);
|
||||||
BuildMI(MBB, MI, DL, get(Teak::SHFI2_ab_ab), dstReg)
|
BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), dstReg)
|
||||||
.addReg(dstReg)
|
.addReg(dstReg)
|
||||||
.addImm(16);
|
.addImm(16);
|
||||||
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), dstReg)
|
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), dstReg)
|
||||||
@ -552,7 +552,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
|
|||||||
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), Teak::A0)
|
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), Teak::A0)
|
||||||
.addReg(Teak::R7)
|
.addReg(Teak::R7)
|
||||||
.addImm(frameOffset);
|
.addImm(frameOffset);
|
||||||
BuildMI(MBB, MI, DL, get(Teak::SHFI2_ab_ab), Teak::A0)
|
BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), Teak::A0)
|
||||||
.addReg(Teak::A0)
|
.addReg(Teak::A0)
|
||||||
.addImm(16);
|
.addImm(16);
|
||||||
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), Teak::A0)
|
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), Teak::A0)
|
||||||
@ -580,6 +580,54 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
|
|||||||
MBB.erase(MI);
|
MBB.erase(MI);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// case Teak::SHL_PSEUDO_ab_ab_sv:
|
||||||
|
// {
|
||||||
|
// BuildMI(MBB, MI, DL, get(Teak::MOV_regnobp016_regnob16), Teak::SV)
|
||||||
|
// .addReg(MI.getOperand(2).getReg());
|
||||||
|
// BuildMI(MBB, MI, DL, get(Teak::SHFC_ab_ab_sv), MI.getOperand(0).getReg())
|
||||||
|
// .addReg(MI.getOperand(1).getReg());
|
||||||
|
// .addReg(MI.getOperand(2).getReg());
|
||||||
|
// MBB.erase(MI);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
case Teak::SHFI_logic_ab_ab:
|
||||||
|
{
|
||||||
|
BuildMI(MBB, MI, DL, get(Teak::SET_imm16_sttmod), Teak::MOD0)
|
||||||
|
.addImm(0x80)
|
||||||
|
.addReg(Teak::MOD0);
|
||||||
|
BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), MI.getOperand(0).getReg())
|
||||||
|
.add(MI.getOperand(1))
|
||||||
|
.add(MI.getOperand(2));
|
||||||
|
BuildMI(MBB, MI, DL, get(Teak::RST_imm16_sttmod), Teak::MOD0)
|
||||||
|
.addImm(0x80)
|
||||||
|
.addReg(Teak::MOD0);
|
||||||
|
MBB.erase(MI);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case Teak::SHFC_logic_ab_ab_sv:
|
||||||
|
{
|
||||||
|
BuildMI(MBB, MI, DL, get(Teak::SET_imm16_sttmod), Teak::MOD0)
|
||||||
|
.addImm(0x80)
|
||||||
|
.addReg(Teak::MOD0);
|
||||||
|
BuildMI(MBB, MI, DL, get(Teak::SHFC_arith_ab_ab_sv), MI.getOperand(0).getReg())
|
||||||
|
.add(MI.getOperand(1))
|
||||||
|
.add(MI.getOperand(2));
|
||||||
|
BuildMI(MBB, MI, DL, get(Teak::RST_imm16_sttmod), Teak::MOD0)
|
||||||
|
.addImm(0x80)
|
||||||
|
.addReg(Teak::MOD0);
|
||||||
|
MBB.erase(MI);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// case Teak::SRA_PSEUDO_ab_ab_sv:
|
||||||
|
// {
|
||||||
|
// BuildMI(MBB, MI, DL, get(Teak::MOV_regnobp016_regnob16), Teak::SV)
|
||||||
|
// .addReg(MI.getOperand(2).getReg());
|
||||||
|
// BuildMI(MBB, MI, DL, get(Teak::SHFC_ab_ab_sv), MI.getOperand(0).getReg())
|
||||||
|
// .addReg(MI.getOperand(1).getReg());
|
||||||
|
// .addReg(MI.getOperand(2).getReg());
|
||||||
|
// MBB.erase(MI);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
// switch (MI->getOpcode())
|
// switch (MI->getOpcode())
|
||||||
// {
|
// {
|
||||||
|
@ -15,11 +15,18 @@ class ImmAsmOperand<int Low, int High> : AsmOperandClass {
|
|||||||
let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]";
|
let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
def Imm0_63AsmOperand: ImmAsmOperand<0,63> { let Name = "Imm0_63"; }
|
def Imm0_31AsmOperand: ImmAsmOperand<0,31> { let Name = "Imm0_31"; }
|
||||||
def imm0_63 : Operand<i40>, ImmLeaf<i40, [{
|
def imm0_31 : Operand<i40>, ImmLeaf<i40, [{
|
||||||
return Imm >= 0 && Imm < 63;
|
return Imm >= 0 && Imm <= 31;
|
||||||
}]> {
|
}]> {
|
||||||
let ParserMatchClass = Imm0_63AsmOperand;
|
let ParserMatchClass = Imm0_31AsmOperand;
|
||||||
|
}
|
||||||
|
|
||||||
|
def Imm6sAsmOperand: ImmAsmOperand<-32,31> { let Name = "Imm6s"; }
|
||||||
|
def Imm6s : Operand<i16>, ImmLeaf<i16, [{
|
||||||
|
return Imm >= -32 && Imm <= 31;
|
||||||
|
}]> {
|
||||||
|
let ParserMatchClass = Imm6sAsmOperand;
|
||||||
}
|
}
|
||||||
|
|
||||||
def Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; }
|
def Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; }
|
||||||
@ -125,6 +132,48 @@ def OR_imm16_a : InstTeakImm16<
|
|||||||
"or $val, $a",
|
"or $val, $a",
|
||||||
[(set ARegs:$dst, (or ARegs:$a, imm0_65535:$val))]>;
|
[(set ARegs:$dst, (or ARegs:$a, imm0_65535:$val))]>;
|
||||||
|
|
||||||
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
|
def RST_imm16_regnob16 : InstTeakImm16<
|
||||||
|
(outs RegNoBRegs16:$dst),
|
||||||
|
(ins imm0_65535_16:$val, RegNoBRegs16:$a),
|
||||||
|
"rst $val, $a",
|
||||||
|
[(set RegNoBRegs16:$dst, (and RegNoBRegs16:$a, (not imm0_65535_16:$val)))]>;
|
||||||
|
|
||||||
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
|
def RST_imm16_abl : InstTeakImm16<
|
||||||
|
(outs ABRegs:$dst),
|
||||||
|
(ins imm0_65535:$val, ABRegs:$a),
|
||||||
|
"rst $val, ${a}l",
|
||||||
|
[(set ABRegs:$dst, (and ABRegs:$a, (not imm0_65535:$val)))]>;
|
||||||
|
|
||||||
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
|
def RST_imm16_sttmod : InstTeakImm16<
|
||||||
|
(outs SttModRegs:$dst),
|
||||||
|
(ins imm0_65535_16:$val, SttModRegs:$a),
|
||||||
|
"rst $val, $a",
|
||||||
|
[]>;
|
||||||
|
|
||||||
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
|
def SET_imm16_regnob16 : InstTeakImm16<
|
||||||
|
(outs RegNoBRegs16:$dst),
|
||||||
|
(ins imm0_65535_16:$val, RegNoBRegs16:$a),
|
||||||
|
"set $val, $a",
|
||||||
|
[(set RegNoBRegs16:$dst, (or RegNoBRegs16:$a, imm0_65535_16:$val))]>;
|
||||||
|
|
||||||
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
|
def SET_imm16_abl : InstTeakImm16<
|
||||||
|
(outs ABRegs:$dst),
|
||||||
|
(ins imm0_65535:$val, ABRegs:$a),
|
||||||
|
"set $val, ${a}l",
|
||||||
|
[(set ABRegs:$dst, (or ABRegs:$a, imm0_65535:$val))]>;
|
||||||
|
|
||||||
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
|
def SET_imm16_sttmod : InstTeakImm16<
|
||||||
|
(outs SttModRegs:$dst),
|
||||||
|
(ins imm0_65535_16:$val, SttModRegs:$a),
|
||||||
|
"set $val, $a",
|
||||||
|
[]>;
|
||||||
|
|
||||||
let Defs = [ICC], Constraints = "$dst = $a" in
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
def OR_r7offset16_a : InstTeakImm16<
|
def OR_r7offset16_a : InstTeakImm16<
|
||||||
(outs ARegs:$dst),
|
(outs ARegs:$dst),
|
||||||
@ -230,6 +279,13 @@ def MOV_regnobp016_abl : InstTeak<
|
|||||||
"mov $src, ${dst}l",
|
"mov $src, ${dst}l",
|
||||||
[(set ABRegs:$dst, (zext RegNoBRegs16:$src))]>;
|
[(set ABRegs:$dst, (zext RegNoBRegs16:$src))]>;
|
||||||
|
|
||||||
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
|
def NEG_a : InstTeak<
|
||||||
|
(outs ARegs:$dst),
|
||||||
|
(ins ARegs:$a),
|
||||||
|
"neg $a",
|
||||||
|
[(set ARegs:$dst, (ineg ARegs:$a))]>;
|
||||||
|
|
||||||
let Defs = [ICC], Constraints = "$dst = $a" in
|
let Defs = [ICC], Constraints = "$dst = $a" in
|
||||||
def NOT_a : InstTeak<
|
def NOT_a : InstTeak<
|
||||||
(outs ARegs:$dst),
|
(outs ARegs:$dst),
|
||||||
@ -238,25 +294,74 @@ def NOT_a : InstTeak<
|
|||||||
[(set ARegs:$dst, (not ARegs:$a))]>;
|
[(set ARegs:$dst, (not ARegs:$a))]>;
|
||||||
|
|
||||||
let Defs = [ICC] in
|
let Defs = [ICC] in
|
||||||
def SHFI_ab_ab : InstTeak<
|
def SHFI_arith_ab_ab : InstTeak<
|
||||||
(outs ABRegs:$dst),
|
(outs ABRegs:$dst),
|
||||||
(ins ABRegs:$src, imm0_63:$shift),
|
(ins ABRegs:$src, Imm6s:$shift),
|
||||||
"shfi $src, $dst, -$shift",
|
"shfi $src, $dst, $shift",
|
||||||
[(set ABRegs:$dst, (sra ABRegs:$src, imm0_63:$shift))]>;
|
[(set ABRegs:$dst, (TeakShiftArith ABRegs:$src, Imm6s:$shift))]>;
|
||||||
|
|
||||||
let Defs = [ICC] in
|
let Defs = [ICC] in
|
||||||
def SHFI2_ab_ab : InstTeak<
|
def SHFI_logic_ab_ab : TeakPseudoInst<
|
||||||
(outs ABRegs:$dst),
|
(outs ABRegs:$dst),
|
||||||
(ins ABRegs:$src, imm0_63:$shift),
|
(ins ABRegs:$src, Imm6s:$shift),
|
||||||
"shfi $src, $dst, +$shift",
|
"shfi $src, $dst, $shift",
|
||||||
[(set ABRegs:$dst, (shl ABRegs:$src, imm0_63:$shift))]>;
|
[(set ABRegs:$dst, (TeakShiftLogic ABRegs:$src, Imm6s:$shift))]>;
|
||||||
|
|
||||||
let Defs = [ICC] in
|
let Defs = [ICC] in
|
||||||
def SHFI3_ab_ab : InstTeak<
|
def SHFC_arith_ab_ab_sv : InstTeak<
|
||||||
(outs ABRegs:$dst),
|
(outs ABRegs:$dst),
|
||||||
(ins ABRegs:$src, imm0_63:$shift),
|
(ins ABRegs:$src, SVReg:$shift),
|
||||||
"shfi $src, $dst, -$shift",
|
"shfc $src, $dst, always",
|
||||||
[(set ABRegs:$dst, (srl ABRegs:$src, imm0_63:$shift))]>;
|
[(set ABRegs:$dst, (TeakShiftArith ABRegs:$src, SVReg:$shift))]>;
|
||||||
|
|
||||||
|
let Defs = [ICC] in
|
||||||
|
def SHFC_logic_ab_ab_sv : TeakPseudoInst<
|
||||||
|
(outs ABRegs:$dst),
|
||||||
|
(ins ABRegs:$src, SVReg:$shift),
|
||||||
|
"shfc $src, $dst, always",
|
||||||
|
[(set ABRegs:$dst, (TeakShiftLogic ABRegs:$src, SVReg:$shift))]>;
|
||||||
|
|
||||||
|
// let Defs = [ICC, SV] in
|
||||||
|
// def SRL_PSEUDO_ab_ab_sv : TeakPseudoInst<
|
||||||
|
// (outs ABRegs:$dst),
|
||||||
|
// (ins ABRegs:$src, RegNoBRegs16:$shift),
|
||||||
|
// "SRL_PSEUDO_ab_sv",
|
||||||
|
// [(set ABRegs:$dst, (srl ABRegs:$x, RegNoBRegs16:$y))]>;
|
||||||
|
|
||||||
|
// let Defs = [ICC, SV] in
|
||||||
|
// def SRA_PSEUDO_ab_ab_sv : TeakPseudoInst<
|
||||||
|
// (outs ABRegs:$dst),
|
||||||
|
// (ins ABRegs:$src, RegNoBRegs16:$shift),
|
||||||
|
// "SRA_PSEUDO_ab_sv",
|
||||||
|
// [(set ABRegs:$dst, (sra ABRegs:$x, RegNoBRegs16:$y))]>;
|
||||||
|
|
||||||
|
// let Defs = [ICC, SV] in
|
||||||
|
// def SHL_PSEUDO_ab_ab_sv : TeakPseudoInst<
|
||||||
|
// (outs ABRegs:$dst),
|
||||||
|
// (ins ABRegs:$src, RegNoBRegs16:$shift),
|
||||||
|
// "SHL_PSEUDO_ab_sv",
|
||||||
|
// [(set ABRegs:$dst, (shl ABRegs:$x, RegNoBRegs16:$y))]>;
|
||||||
|
|
||||||
|
// let Defs = [ICC] in
|
||||||
|
// def SHFI_ab_ab : InstTeak<
|
||||||
|
// (outs ABRegs:$dst),
|
||||||
|
// (ins ABRegs:$src, imm0_31:$shift),
|
||||||
|
// "shfi $src, $dst, -$shift",
|
||||||
|
// [(set ABRegs:$dst, (sra ABRegs:$src, imm0_31:$shift))]>;
|
||||||
|
|
||||||
|
// let Defs = [ICC] in
|
||||||
|
// def SHFI2_ab_ab : InstTeak<
|
||||||
|
// (outs ABRegs:$dst),
|
||||||
|
// (ins ABRegs:$src, imm0_31:$shift),
|
||||||
|
// "shfi $src, $dst, +$shift",
|
||||||
|
// [(set ABRegs:$dst, (shl ABRegs:$src, imm0_31:$shift))]>;
|
||||||
|
|
||||||
|
// let Defs = [ICC] in
|
||||||
|
// def SHFI3_ab_ab : InstTeak<
|
||||||
|
// (outs ABRegs:$dst),
|
||||||
|
// (ins ABRegs:$src, imm0_31:$shift),
|
||||||
|
// "shfi $src, $dst, -$shift",
|
||||||
|
// [(set ABRegs:$dst, (srl ABRegs:$src, imm0_31:$shift))]>;
|
||||||
|
|
||||||
let Defs = [ICC] in
|
let Defs = [ICC] in
|
||||||
def MPY_y0_regnob16 : InstTeak<
|
def MPY_y0_regnob16 : InstTeak<
|
||||||
@ -318,7 +423,7 @@ def HI16 : SDNodeXForm<imm, [{
|
|||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
// Arbitrary immediates.
|
// Arbitrary immediates.
|
||||||
def : Pat<(i40 imm:$val), (OR_imm16_a (LO16 imm:$val), (MOV_imm16hi_ab (HI16 imm:$val)))>;
|
def : Pat<(i40 imm:$val), (SET_imm16_abl (LO16 imm:$val), (MOV_imm16hi_ab (HI16 imm:$val)))>;
|
||||||
|
|
||||||
let mayStore = 1 in
|
let mayStore = 1 in
|
||||||
def MOV_al2_memimm16 : InstTeakImm16<
|
def MOV_al2_memimm16 : InstTeakImm16<
|
||||||
|
@ -66,6 +66,10 @@ def addr : ComplexPattern<iPTR, 2, "SelectAddr", [frameindex], []>;
|
|||||||
def SDT_TeakWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
|
def SDT_TeakWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
|
||||||
def TeakWrapper : SDNode<"TeakISD::WRAPPER", SDT_TeakWrapper>;
|
def TeakWrapper : SDNode<"TeakISD::WRAPPER", SDT_TeakWrapper>;
|
||||||
|
|
||||||
|
def SDT_TeakShift : SDTypeProfile<1, 2, [SDTCisVT<0, i40>, SDTCisVT<1, i40>, SDTCisInt<2>]>;
|
||||||
|
def TeakShiftArith : SDNode<"TeakISD::SHIFT_ARITH", SDT_TeakShift>;
|
||||||
|
def TeakShiftLogic : SDNode<"TeakISD::SHIFT_LOGIC", SDT_TeakShift>;
|
||||||
|
|
||||||
// //===----------------------------------------------------------------------===//
|
// //===----------------------------------------------------------------------===//
|
||||||
// // Operand Definitions.
|
// // Operand Definitions.
|
||||||
// //===----------------------------------------------------------------------===//
|
// //===----------------------------------------------------------------------===//
|
||||||
|
@ -56,7 +56,7 @@ BitVector TeakRegisterInfo::getReservedRegs(const MachineFunction &MF) const
|
|||||||
Reserved.set(Teak::PC);
|
Reserved.set(Teak::PC);
|
||||||
Reserved.set(Teak::R7);
|
Reserved.set(Teak::R7);
|
||||||
Reserved.set(Teak::LC);
|
Reserved.set(Teak::LC);
|
||||||
Reserved.set(Teak::SV);
|
//Reserved.set(Teak::SV);
|
||||||
return Reserved;
|
return Reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +106,8 @@ unsigned TeakRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, Ma
|
|||||||
return 0;
|
return 0;
|
||||||
case Teak::GRRegsRegClassID:
|
case Teak::GRRegsRegClassID:
|
||||||
return 5;
|
return 5;
|
||||||
|
case Teak::SVRegRegClassID:
|
||||||
|
return 0;
|
||||||
case Teak::ABRegsRegClassID:
|
case Teak::ABRegsRegClassID:
|
||||||
return 4;
|
return 4;
|
||||||
case Teak::ALRegsRegClassID:
|
case Teak::ALRegsRegClassID:
|
||||||
@ -251,6 +253,11 @@ bool TeakRegisterInfo::shouldCoalesce(MachineInstr *MI, const TargetRegisterClas
|
|||||||
dbgs() << "DstSubReg: " << DstSubReg << "\n";
|
dbgs() << "DstSubReg: " << DstSubReg << "\n";
|
||||||
dbgs() << "NewRC: " << NewRC->getID() << "\n";
|
dbgs() << "NewRC: " << NewRC->getID() << "\n";
|
||||||
|
|
||||||
|
if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
|
||||||
|
DstRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
|
||||||
|
NewRC->hasSuperClassEq(&Teak::SVRegRegClass))
|
||||||
|
return false;
|
||||||
|
|
||||||
if(DstSubReg == Teak::sub_16bit)
|
if(DstSubReg == Teak::sub_16bit)
|
||||||
return true;
|
return true;
|
||||||
//if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass))
|
//if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass))
|
||||||
|
@ -87,6 +87,13 @@ def VTR1 : TeakReg<0, "vtr1">;
|
|||||||
def PRPAGE : TeakReg<0, "prpage">;
|
def PRPAGE : TeakReg<0, "prpage">;
|
||||||
|
|
||||||
def STT0 : TeakReg<0, "stt0">;
|
def STT0 : TeakReg<0, "stt0">;
|
||||||
|
def STT1 : TeakReg<0, "stt1">;
|
||||||
|
def STT2 : TeakReg<0, "stt2">;
|
||||||
|
|
||||||
|
def MOD0 : TeakReg<0, "mod0">;
|
||||||
|
def MOD1 : TeakReg<0, "mod1">;
|
||||||
|
def MOD2 : TeakReg<0, "mod2">;
|
||||||
|
def MOD3 : TeakReg<0, "mod3">;
|
||||||
|
|
||||||
def ICC : TeakReg<0, "ICC">;//for flag setting ops, maybe rename
|
def ICC : TeakReg<0, "ICC">;//for flag setting ops, maybe rename
|
||||||
|
|
||||||
@ -115,6 +122,9 @@ def FP : RegisterClass<"Teak", [i16], 16, (add R7)>;
|
|||||||
def Y0Regs : RegisterClass<"Teak", [i16], 16, (add Y0)>;
|
def Y0Regs : RegisterClass<"Teak", [i16], 16, (add Y0)>;
|
||||||
def P0Regs : RegisterClass<"Teak", [i32], 32, (add P0)>;
|
def P0Regs : RegisterClass<"Teak", [i32], 32, (add P0)>;
|
||||||
def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>;
|
def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>;
|
||||||
|
def SVReg : RegisterClass<"Teak", [i16], 16, (add SV)>;
|
||||||
//def XRegs : RegisterClass<"Teak", [i16], 16, (add X0, X1)>;
|
//def XRegs : RegisterClass<"Teak", [i16], 16, (add X0, X1)>;
|
||||||
//def YRegs : RegisterClass<"Teak", [i16], 16, (add Y0, Y1)>;
|
//def YRegs : RegisterClass<"Teak", [i16], 16, (add Y0, Y1)>;
|
||||||
//def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>;
|
//def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>;
|
||||||
|
|
||||||
|
def SttModRegs : RegisterClass<"Teak", [i16], 16, (add STT0, STT1, STT2, MOD0, MOD1, MOD2, MOD3)>;
|
Loading…
Reference in New Issue
Block a user