diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp index f3af42c4f3f..56223bc17c0 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp @@ -272,6 +272,13 @@ static unsigned encodeArArpSttModOp(unsigned reg) switch (reg) { 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: dbgs() << "encodeArArpSttModOp(" << reg << ")\n"; 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, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const @@ -416,7 +442,10 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, unsigned dstReg = MI.getOperand(0).getReg(); if(MI.getOpcode() == Teak::MOV_regnobp016_abl) dstReg = teakGetAbLReg(dstReg); - EmitConstant(0x5800 | encodeRegisterP0Op(MI.getOperand(1).getReg()) | (encodeRegisterOp(dstReg) << 5), 2, OS); + 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); break; } case Teak::MOV_regnob16_memrn: @@ -475,6 +504,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case Teak::MPY_y0_regnob16: EmitConstant(0x8040 | encodeRegisterOp(MI.getOperand(2).getReg()), 2, OS); break; + case Teak::NEG_a: + EmitConstant(0x6790 | (encodeAxOp(MI.getOperand(0).getReg()) << 12), 2, OS); + break; case Teak::NOT_a: EmitConstant(0x6780 | (encodeAxOp(MI.getOperand(0).getReg()) << 12), 2, OS); 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(MI.getOperand(2).getImm() & 0xFFFF, 2, OS); break; - //todo: these three should be pseudo ops - case Teak::SHFI_ab_ab: - case Teak::SHFI2_ab_ab: - case Teak::SHFI3_ab_ab: + + case Teak::RST_imm16_regnob16: + case Teak::RST_imm16_abl: + { + 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 | (encodeAbOp(MI.getOperand(1).getReg()) << 10) | (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; 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); break; 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); break; case Teak::XOR_regnobp016_a: diff --git a/llvm/lib/Target/Teak/TeakCallingConv.td b/llvm/lib/Target/Teak/TeakCallingConv.td index b5434d15674..07655f43a5b 100644 --- a/llvm/lib/Target/Teak/TeakCallingConv.td +++ b/llvm/lib/Target/Teak/TeakCallingConv.td @@ -55,5 +55,5 @@ def CC_Teak : CallingConv<[ //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)>; \ No newline at end of file diff --git a/llvm/lib/Target/Teak/TeakISelLowering.cpp b/llvm/lib/Target/Teak/TeakISelLowering.cpp index 6da2a4c3894..a7c494cfa30 100644 --- a/llvm/lib/Target/Teak/TeakISelLowering.cpp +++ b/llvm/lib/Target/Teak/TeakISelLowering.cpp @@ -98,11 +98,15 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM) setOperationAction(ISD::ADD, MVT::i16, Custom); setOperationAction(ISD::AND, MVT::i16, Custom); + setOperationAction(ISD::XOR, MVT::i16, Custom); setOperationAction(ISD::OR, MVT::i16, Custom); setOperationAction(ISD::SUB, 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::i40, Custom); setOperationAction(ISD::SRA, MVT::i16, Custom); + setOperationAction(ISD::SRA, MVT::i40, Custom); setStackPointerRegisterToSaveRestore(Teak::SP); @@ -343,6 +347,7 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::AND: case ISD::OR: case ISD::SUB: + case ISD::XOR: { const SDNode *N = Op.getNode(); 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); } case ISD::SHL: + { + 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::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: { - 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); + 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: // { // const SDNode *N = Op.getNode(); diff --git a/llvm/lib/Target/Teak/TeakISelLowering.h b/llvm/lib/Target/Teak/TeakISelLowering.h index e08dcfb5765..862bc3a64f9 100644 --- a/llvm/lib/Target/Teak/TeakISelLowering.h +++ b/llvm/lib/Target/Teak/TeakISelLowering.h @@ -38,7 +38,9 @@ enum NodeType { CMPICC, BRICC, SELECT_ICC, - WRAPPER + WRAPPER, + SHIFT_ARITH, + SHIFT_LOGIC }; } diff --git a/llvm/lib/Target/Teak/TeakInstrInfo.cpp b/llvm/lib/Target/Teak/TeakInstrInfo.cpp index fe457f9171d..1ff61a4bf4b 100644 --- a/llvm/lib/Target/Teak/TeakInstrInfo.cpp +++ b/llvm/lib/Target/Teak/TeakInstrInfo.cpp @@ -537,7 +537,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg) .addReg(Teak::R7) .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) .addImm(16); 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) .addReg(Teak::R7) .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) .addImm(16); BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), Teak::A0) @@ -580,6 +580,54 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const MBB.erase(MI); 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()) // { diff --git a/llvm/lib/Target/Teak/TeakInstrInfo.td b/llvm/lib/Target/Teak/TeakInstrInfo.td index dd92d8336a0..53165a5eba4 100644 --- a/llvm/lib/Target/Teak/TeakInstrInfo.td +++ b/llvm/lib/Target/Teak/TeakInstrInfo.td @@ -15,11 +15,18 @@ class ImmAsmOperand : AsmOperandClass { let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]"; } -def Imm0_63AsmOperand: ImmAsmOperand<0,63> { let Name = "Imm0_63"; } -def imm0_63 : Operand, ImmLeaf= 0 && Imm < 63; +def Imm0_31AsmOperand: ImmAsmOperand<0,31> { let Name = "Imm0_31"; } +def imm0_31 : Operand, ImmLeaf= 0 && Imm <= 31; }]> { - let ParserMatchClass = Imm0_63AsmOperand; + let ParserMatchClass = Imm0_31AsmOperand; +} + +def Imm6sAsmOperand: ImmAsmOperand<-32,31> { let Name = "Imm6s"; } +def Imm6s : Operand, ImmLeaf= -32 && Imm <= 31; +}]> { + let ParserMatchClass = Imm6sAsmOperand; } def Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; } @@ -125,6 +132,48 @@ def OR_imm16_a : InstTeakImm16< "or $val, $a", [(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 def OR_r7offset16_a : InstTeakImm16< (outs ARegs:$dst), @@ -230,6 +279,13 @@ def MOV_regnobp016_abl : InstTeak< "mov $src, ${dst}l", [(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 def NOT_a : InstTeak< (outs ARegs:$dst), @@ -238,25 +294,74 @@ def NOT_a : InstTeak< [(set ARegs:$dst, (not ARegs:$a))]>; let Defs = [ICC] in -def SHFI_ab_ab : InstTeak< +def SHFI_arith_ab_ab : InstTeak< (outs ABRegs:$dst), - (ins ABRegs:$src, imm0_63:$shift), - "shfi $src, $dst, -$shift", - [(set ABRegs:$dst, (sra ABRegs:$src, imm0_63:$shift))]>; + (ins ABRegs:$src, Imm6s:$shift), + "shfi $src, $dst, $shift", + [(set ABRegs:$dst, (TeakShiftArith ABRegs:$src, Imm6s:$shift))]>; let Defs = [ICC] in -def SHFI2_ab_ab : InstTeak< +def SHFI_logic_ab_ab : TeakPseudoInst< (outs ABRegs:$dst), - (ins ABRegs:$src, imm0_63:$shift), - "shfi $src, $dst, +$shift", - [(set ABRegs:$dst, (shl ABRegs:$src, imm0_63:$shift))]>; + (ins ABRegs:$src, Imm6s:$shift), + "shfi $src, $dst, $shift", + [(set ABRegs:$dst, (TeakShiftLogic ABRegs:$src, Imm6s:$shift))]>; let Defs = [ICC] in -def SHFI3_ab_ab : InstTeak< +def SHFC_arith_ab_ab_sv : InstTeak< (outs ABRegs:$dst), - (ins ABRegs:$src, imm0_63:$shift), - "shfi $src, $dst, -$shift", - [(set ABRegs:$dst, (srl ABRegs:$src, imm0_63:$shift))]>; + (ins ABRegs:$src, SVReg:$shift), + "shfc $src, $dst, always", + [(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 def MPY_y0_regnob16 : InstTeak< @@ -318,7 +423,7 @@ def HI16 : SDNodeXForm; // 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 def MOV_al2_memimm16 : InstTeakImm16< diff --git a/llvm/lib/Target/Teak/TeakOperators.td b/llvm/lib/Target/Teak/TeakOperators.td index fd3a20680d7..059ebe1bcaa 100644 --- a/llvm/lib/Target/Teak/TeakOperators.td +++ b/llvm/lib/Target/Teak/TeakOperators.td @@ -66,6 +66,10 @@ def addr : ComplexPattern; def SDT_TeakWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 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. // //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Teak/TeakRegisterInfo.cpp b/llvm/lib/Target/Teak/TeakRegisterInfo.cpp index 4fd996ae087..4aca214d638 100644 --- a/llvm/lib/Target/Teak/TeakRegisterInfo.cpp +++ b/llvm/lib/Target/Teak/TeakRegisterInfo.cpp @@ -56,7 +56,7 @@ BitVector TeakRegisterInfo::getReservedRegs(const MachineFunction &MF) const Reserved.set(Teak::PC); Reserved.set(Teak::R7); Reserved.set(Teak::LC); - Reserved.set(Teak::SV); + //Reserved.set(Teak::SV); return Reserved; } @@ -106,6 +106,8 @@ unsigned TeakRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, Ma return 0; case Teak::GRRegsRegClassID: return 5; + case Teak::SVRegRegClassID: + return 0; case Teak::ABRegsRegClassID: return 4; case Teak::ALRegsRegClassID: @@ -251,6 +253,11 @@ bool TeakRegisterInfo::shouldCoalesce(MachineInstr *MI, const TargetRegisterClas dbgs() << "DstSubReg: " << DstSubReg << "\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) return true; //if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass)) diff --git a/llvm/lib/Target/Teak/TeakRegisterInfo.td b/llvm/lib/Target/Teak/TeakRegisterInfo.td index ec34b3fdccd..b6bd744dd89 100644 --- a/llvm/lib/Target/Teak/TeakRegisterInfo.td +++ b/llvm/lib/Target/Teak/TeakRegisterInfo.td @@ -87,6 +87,13 @@ def VTR1 : TeakReg<0, "vtr1">; def PRPAGE : TeakReg<0, "prpage">; 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 @@ -115,6 +122,9 @@ def FP : RegisterClass<"Teak", [i16], 16, (add R7)>; def Y0Regs : RegisterClass<"Teak", [i16], 16, (add Y0)>; def P0Regs : RegisterClass<"Teak", [i32], 32, (add P0)>; 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 YRegs : RegisterClass<"Teak", [i16], 16, (add Y0, Y1)>; -//def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>; \ No newline at end of file +//def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>; + +def SttModRegs : RegisterClass<"Teak", [i16], 16, (add STT0, STT1, STT2, MOD0, MOD1, MOD2, MOD3)>; \ No newline at end of file