diff --git a/lib/Target/CSKY/CSKYInstrInfo.td b/lib/Target/CSKY/CSKYInstrInfo.td index 720ce86aa6d..20adda4f9ca 100644 --- a/lib/Target/CSKY/CSKYInstrInfo.td +++ b/lib/Target/CSKY/CSKYInstrInfo.td @@ -151,73 +151,88 @@ class UnOpFrag : PatFrag<(ops node:$Src), res>; // Basic ALU instructions. //===----------------------------------------------------------------------===// -def ADDI32 : I_12<0x0, "addi32", add, oimm12>; -def SUBI32 : I_12<0x1, "subi32", sub, oimm12>; -def ANDI32 : I_12<0x2, "andi32", and, uimm12>; -def ANDNI32 : I_12<0x3, "andni32", and, nimm12>; -def ORI32 : I_16_ZX<"ori32", uimm16, + def ADDI32 : I_12<0x0, "addi32", add, oimm12>; + def SUBI32 : I_12<0x1, "subi32", sub, oimm12>; + def ORI32 : I_16_ZX<"ori32", uimm16, [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>; -def XORI32 : I_12<0x4, "xori32", xor, uimm12>; -def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32", - (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), - [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>; -def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32", - (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), - [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>; -def ASRI32 : I_5_XZ<0x12, 0x4, "asri32", - (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), - [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>; -def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32", - (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), - [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>; - -def ADDU32 : R_YXZ_SP_F1<0x0, 0x1, - BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>; -def SUBU32 : R_YXZ_SP_F1<0x0, 0x4, - BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">; -def AND32 : R_YXZ_SP_F1<0x8, 0x1, - BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>; -def ANDN32 : R_YXZ_SP_F1<0x8, 0x2, - BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">; -def OR32: R_YXZ_SP_F1<0x9, 0x1, - BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>; -def XOR32 : R_YXZ_SP_F1<0x9, 0x2, - BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>; -def NOR32 : R_YXZ_SP_F1<0x9, 0x4, - BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>; -def LSL32 : R_YXZ_SP_F1<0x10, 0x1, - BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">; -def LSR32 : R_YXZ_SP_F1<0x10, 0x2, - BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">; -def ASR32 : R_YXZ_SP_F1<0x10, 0x4, - BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">; -def MULT32 : R_YXZ_SP_F1<0x21, 0x1, - BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>; -def DIVS32 : R_YXZ_SP_F1<0x20, 0x2, - BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">; -def DIVU32 : R_YXZ_SP_F1<0x20, 0x1, - BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">; -def IXH32 : R_YXZ_SP_F1<0x2, 0x1, - BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">; -def IXW32 : R_YXZ_SP_F1<0x2, 0x2, - BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">; -def IXD32 : R_YXZ_SP_F1<0x2, 0x4, - BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">; - -def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx), - "not32", [(set GPR:$rz, (not GPR:$rx))]>; - -def SEXT : I_5_XZ_U<0x16, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", - []>; -def ZEXT : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32", - []>; + def XORI32 : I_12<0x4, "xori32", xor, uimm12>; + def ANDI32 : I_12<0x2, "andi32", and, uimm12>; + def ANDNI32 : I_12<0x3, "andni32", and, nimm12>; + def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32", + (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), + [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>; + def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32", + (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), + [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>; + def ASRI32 : I_5_XZ<0x12, 0x4, "asri32", + (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), + [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>; + def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32", + (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), + [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>; -let isCommutable = 1 in + def ADDU32 : R_YXZ_SP_F1<0x0, 0x1, + BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>; + def SUBU32 : R_YXZ_SP_F1<0x0, 0x4, + BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">; + def MULT32 : R_YXZ_SP_F1<0x21, 0x1, + BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>; + def AND32 : R_YXZ_SP_F1<0x8, 0x1, + BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>; + def ANDN32 : R_YXZ_SP_F1<0x8, 0x2, + BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">; + def OR32: R_YXZ_SP_F1<0x9, 0x1, + BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>; + def XOR32 : R_YXZ_SP_F1<0x9, 0x2, + BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>; + def NOR32 : R_YXZ_SP_F1<0x9, 0x4, + BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>; + def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx), + "not32", [(set GPR:$rz, (not GPR:$rx))]>; + def LSL32 : R_YXZ_SP_F1<0x10, 0x1, + BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">; + def LSR32 : R_YXZ_SP_F1<0x10, 0x2, + BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">; + def ASR32 : R_YXZ_SP_F1<0x10, 0x4, + BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">; + def ROTL32 : R_YXZ_SP_F1<0x10, 0x8, + BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">; + + // TODO: Shift series instr. with carry. + + def IXH32 : R_YXZ_SP_F1<0x2, 0x1, + BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">; + def IXW32 : R_YXZ_SP_F1<0x2, 0x2, + BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">; + + def IXD32 : R_YXZ_SP_F1<0x2, 0x4, + BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">; + + let isCommutable = 1 in def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>; -def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout), - (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>; + def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout), + (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>; + + // TODO: incf32. + def DIVS32 : R_YXZ_SP_F1<0x20, 0x2, + BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">; + def DIVU32 : R_YXZ_SP_F1<0x20, 0x1, + BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">; + + def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32", + (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; + def DECLT32 : I_5_XZ<0x4, 0x2, "declt32", + (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; + def DECNE32 : I_5_XZ<0x4, 0x4, "decne32", + (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; + + // TODO: s/zext. + def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), + (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>; + def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), + (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>; //===----------------------------------------------------------------------===// // Load & Store instructions. @@ -226,46 +241,63 @@ def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout), def LD32B : I_LD; def LD32H : I_LD; def LD32W : I_LD; -def LD32BS : I_LD; -def LD32HS : I_LD; -def LDR32B : I_LDR<0x0, "ldr32.b">; -def LDR32BS : I_LDR<0x4, "ldr32.bs">; -def LDR32H : I_LDR<0x1, "ldr32.h">; -def LDR32HS : I_LDR<0x5, "ldr32.hs">; -def LDR32W : I_LDR<0x2, "ldr32.w">; + + def LD32BS : I_LD; + def LD32HS : I_LD; + + // TODO: LDM and STM. + def ST32B : I_ST; def ST32H : I_ST; def ST32W : I_ST; -def STR32B : I_STR<0x0, "str32.b">; -def STR32H : I_STR<0x1, "str32.h">; -def STR32W : I_STR<0x2, "str32.w">; + + def LDR32B : I_LDR<0x0, "ldr32.b">; + def LDR32BS : I_LDR<0x4, "ldr32.bs">; + def LDR32H : I_LDR<0x1, "ldr32.h">; + def LDR32HS : I_LDR<0x5, "ldr32.hs">; + def LDR32W : I_LDR<0x2, "ldr32.w">; + def STR32B : I_STR<0x0, "str32.b">; + def STR32H : I_STR<0x1, "str32.h">; + def STR32W : I_STR<0x2, "str32.w">; + + //TODO: SPILL_CARRY and RESTORE_CARRY. //===----------------------------------------------------------------------===// // Compare instructions. //===----------------------------------------------------------------------===// -def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>; -def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>; -def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>; -def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">; -def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">; -def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">; + def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>; + def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>; + def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>; + + + def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">; + def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">; + def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">; + + // TODO: setc and clrc. + // TODO: test32 and tstnbz. //===----------------------------------------------------------------------===// // Data move instructions. //===----------------------------------------------------------------------===// -def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>; -def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>; -def MOV32 : R_XZ<0x12, 0x1, "mov32">; -def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>; -def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>; + def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>; + def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>; + def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>; + def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>; + def MVC32 : R_Z_1<0x1, 0x8, "mvc32">; + def MOV32 : R_XZ<0x12, 0x1, "mov32">; -def MVC32 : R_Z_1<0x1, 0x8, "mvc32">; -def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">; + // TODO: ISEL Pseudo. + + def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">; + // TODO: clrf and clrt. + def CLRF32 : R_Z_2<0xB, 0x1, "clrf32", []>; + def CLRT32 : R_Z_2<0xB, 0x2, "clrt32", []>; //===----------------------------------------------------------------------===// // Branch and call instructions. @@ -283,25 +315,25 @@ let isBranch = 1, isTerminator = 1 in { } -def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>; -def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>; -def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>; -def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>; -def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>; -def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>; + def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>; + def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>; + def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>; + def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>; + def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>; + def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>; -let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { - def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register - def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16), + let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { + def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register + def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16), "jmpi32\t$imm16", []>; -} + } -let isCall = 1, Defs = [ R15 ] in - def JSR32 : I_16_JX<0x7, "jsr32", []>; + let isCall = 1, Defs = [ R15 ] in + def JSR32 : I_16_JX<0x7, "jsr32", []>; -let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in - def JSRI32: I_16_L<0x17, (outs), - (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>; + let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in + def JSRI32: I_16_L<0x17, (outs), + (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>; def BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>; @@ -315,7 +347,8 @@ def BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{ let Defs = [ R15 ]; } -def RTS32 : I_16_RET<0x6, 0xF, "rts32", [(CSKY_RET)]>; + + def RTS32 : I_16_RET<0x6, 0xF, "rts32", [(CSKY_RET)]>; def RTE32 : I_16_RET_I<0, 0, "rte32", []>; @@ -330,5 +363,11 @@ def GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset", let mayLoad = 1, mayStore = 0 in { def LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>; let isCodeGenOnly = 1 in -def LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>; -} \ No newline at end of file +def LRW32_Gen : I_16_Z_L<0x14, "lrw32", + (ins bare_symbol:$src1, constpool_symbol:$imm16), []>; +} + +// TODO: Atomic and fence instructions. +// TODO: Other operations. +// TODO: Special instructions. +// TODO: Pseudo for assembly.