diff --git a/llvm/lib/Target/ARC/ARCInstrFormats.td b/llvm/lib/Target/ARC/ARCInstrFormats.td --- a/llvm/lib/Target/ARC/ARCInstrFormats.td +++ b/llvm/lib/Target/ARC/ARCInstrFormats.td @@ -261,32 +261,6 @@ let Inst{5-0} = subop; } -// Single Operand Immediate Instructions. -// 1-register, unsigned 6-bit immediate Single Operand instruction with -// condition code. -// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0| -// |B[2-0] | 1| 1| subop| F|B[5-3] |U6 |1|cc | -class F32_SOP_CC_RU6 major, bits<6> subop, bit F, dag outs, dag ins, - string asmstr, list pattern> : - InstARC<4, outs, ins, asmstr, pattern> { - - bits<5> cc; - bits<6> U6; - bits<6> B; - - let Inst{31-27} = major; - let Inst{26-24} = B{2-0}; - let Inst{23-22} = 0b11; - let Inst{21-16} = subop; - let Inst{15} = F; - let Inst{14-12} = B{5-3}; - let Inst{11-6} = U6; - let Inst{5} = 1; - let Inst{4-0} = cc; - - let DecoderMethod = "DecodeCCRU6Instruction"; -} - // Dual Operand Instructions. Inst[21-16] specifies the specific operation // for this format. @@ -353,6 +327,31 @@ let Inst{5-0} = A; } +// 1-register, unsigned 6-bit, immediate Dual Operand instruction with +// condition code. +// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0| +// |B[2-0] | 1| 1| subop| F|B[5-3] |U6 |1|cc | +class F32_DOP_CC_RU6 major, bits<6> subop, bit F, dag outs, dag ins, + string asmstr, list pattern> : + InstARC<4, outs, ins, asmstr, pattern> { + + bits<5> cc; + bits<6> U6; + bits<6> B; + + let Inst{31-27} = major; + let Inst{26-24} = B{2-0}; + let Inst{23-22} = 0b11; + let Inst{21-16} = subop; + let Inst{15} = F; + let Inst{14-12} = B{5-3}; + let Inst{11-6} = U6; + let Inst{5} = 1; + let Inst{4-0} = cc; + + let DecoderMethod = "DecodeCCRU6Instruction"; +} + // 2-register, unsigned 6-bit immediate Dual Operand instruction with // condition code. This instruction uses B as the first 2 operands // (i.e, add.cc B, B, u6). @@ -364,7 +363,6 @@ bits<5> cc; bits<6> U6; bits<6> B; - bits<6> A; let Inst{31-27} = major; let Inst{26-24} = B{2-0}; diff --git a/llvm/lib/Target/ARC/ARCInstrInfo.td b/llvm/lib/Target/ARC/ARCInstrInfo.td --- a/llvm/lib/Target/ARC/ARCInstrInfo.td +++ b/llvm/lib/Target/ARC/ARCInstrInfo.td @@ -337,24 +337,30 @@ (outs GPR32:$B), (ins immU6:$U6), "mov\t$B, $U6", []>; +def MOV_f_ru6 : F32_DOP_RU6<0b00100, 0b001010, 1, + (outs GPR32:$B), (ins u6:$U6), + "mov.f\t$B, $U6", []> { + let isAsCheapAsAMove=1; + let Defs = [STATUS32]; +} + def cmov : PatFrag<(ops node:$op1, node:$op2, node:$cc), (ARCcmov $op1, $op2, $cc)>; -let Uses = [STATUS32] in { - def MOVcc : F32_DOP_CC_RR<0b00100, 0b001010, 0, - (outs GPR32:$B), - (ins GPR32:$C, GPR32:$fval, cmovpred:$cc), - !strconcat("mov.", "$cc\t$B, $C"), - [(set GPR32:$B, (cmov i32:$C, i32:$fval, cmovpred:$cc))]> { - let Constraints = "$B = $fval"; - } - - def MOVcc_ru6 : F32_SOP_CC_RU6<0b00100, 0b001010, 0, - (outs GPR32:$b), (ins u6:$c, CCOp:$cc, GPR32:$b2), - "mov.$cc\t$b, $c", []> { - let isAsCheapAsAMove=0; - let isPredicable=1; - let isReMaterializable=0; - let Constraints="$b2 = $b"; +let Uses = [STATUS32], isAsCheapAsAMove = 1, isPredicable=1, + isReMaterializable = 0, Constraints = "$B = $B2" in { + def MOV_cc : F32_DOP_CC_RR<0b00100, 0b001010, 0, + (outs GPR32:$B), (ins GPR32:$C, GPR32:$B2, cmovpred:$cc), + "mov.$cc\t$B, $C", + [(set GPR32:$B, (cmov i32:$C, i32:$B2, cmovpred:$cc))]>; + + def MOV_cc_ru6 : F32_DOP_CC_RU6<0b00100, 0b001010, 0, + (outs GPR32:$B), (ins u6:$C, CCOp:$cc, GPR32:$B2), + "mov.$cc\t$B, $C", []>; + + def MOV_cc_f_ru6 : F32_DOP_CC_RU6<0b00100, 0b001010, 1, + (outs GPR32:$B), (ins u6:$C, CCOp:$cc, GPR32:$B2), + "mov.$cc.f\t$B, $C", []> { + let Defs = [STATUS32]; } } diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -304,7 +304,7 @@ DstB = decodeBField(Insn); DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder); using Field = decltype(Insn); - Field U6Field = fieldFromInstruction(Insn, 6, 11); + Field U6Field = fieldFromInstruction(Insn, 6, 6); Inst.addOperand(MCOperand::createImm(U6Field)); Field CCField = fieldFromInstruction(Insn, 0, 4); Inst.addOperand(MCOperand::createImm(CCField)); diff --git a/llvm/test/MC/Disassembler/ARC/alu.txt b/llvm/test/MC/Disassembler/ARC/alu.txt --- a/llvm/test/MC/Disassembler/ARC/alu.txt +++ b/llvm/test/MC/Disassembler/ARC/alu.txt @@ -18,6 +18,60 @@ # CHECK: add %r2, %r7, %r4 0x00 0x27 0x02 0x01 +# CHECK: add.eq %r0, %r0, 1 +0xc0 0x20 0x61 0x00 + +# CHECK: add.lt %r6, %r6, 16 +0xc0 0x26 0x2b 0x04 + +# CHECK: add.le %r15, %r15, 31 +0xc0 0x27 0xec 0x17 + +# CHECK: add.gt %r0, %r0, 1 +0xc0 0x20 0x69 0x00 + +# CHECK: add.ge %r6, %r6, 16 +0xc0 0x26 0x2a 0x04 + +# CHECK: add.p %r15, %r15, 31 +0xc0 0x27 0xe3 0x17 + +# CHECK: add.n %r0, %r0, 1 +0xc0 0x20 0x64 0x00 + +# CHECK: add.vs %r6, %r6, 16 +0xc0 0x26 0x27 0x04 + +# CHECK: add.pnz %r15, %r15, 31 +0xc0 0x27 0xef 0x17 + +# CHECK: add.eq.f %r0, %r0, 1 +0xc0 0x20 0x61 0x80 + +# CHECK: add.lt.f %r6, %r6, 16 +0xc0 0x26 0x2b 0x84 + +# CHECK: add.le.f %r15, %r15, 31 +0xc0 0x27 0xec 0x97 + +# CHECK: add.gt.f %r0, %r0, 1 +0xc0 0x20 0x69 0x80 + +# CHECK: add.ge.f %r6, %r6, 16 +0xc0 0x26 0x2a 0x84 + +# CHECK: add.p.f %r15, %r15, 31 +0xc0 0x27 0xe3 0x97 + +# CHECK: add.n.f %r0, %r0, 1 +0xc0 0x20 0x64 0x80 + +# CHECK: add.vs.f %r6, %r6, 16 +0xc0 0x26 0x27 0x84 + +# CHECK: add.pnz.f %r15, %r15, 31 +0xc0 0x27 0xef 0x97 + # CHECK: and %r2, %r7, %r4 0x04 0x27 0x02 0x01 @@ -33,6 +87,60 @@ # CHECK: and.f %r1, %r1, 255 0x84 0x21 0xc3 0x8f +# CHECK: and.eq %r0, %r0, 0 +0xc4 0x20 0x21 0x00 + +# CHECK: and.lt %r6, %r6, 16 +0xc4 0x26 0x2b 0x04 + +# CHECK: and.le %r15, %r15, 31 +0xc4 0x27 0xec 0x17 + +# CHECK: and.gt %r0, %r0, 0 +0xc4 0x20 0x29 0x00 + +# CHECK: and.ge %r6, %r6, 16 +0xc4 0x26 0x2a 0x04 + +# CHECK: and.p %r15, %r15, 31 +0xc4 0x27 0xe3 0x17 + +# CHECK: and.n %r0, %r0, 0 +0xc4 0x20 0x24 0x00 + +# CHECK: and.vs %r6, %r6, 16 +0xc4 0x26 0x27 0x04 + +# CHECK: and.pnz %r15, %r15, 31 +0xc4 0x27 0xef 0x17 + +# CHECK: and.eq.f %r0, %r0, 0 +0xc4 0x20 0x21 0x80 + +# CHECK: and.lt.f %r6, %r6, 16 +0xc4 0x26 0x2b 0x84 + +# CHECK: and.le.f %r15, %r15, 31 +0xc4 0x27 0xec 0x97 + +# CHECK: and.gt.f %r0, %r0, 0 +0xc4 0x20 0x29 0x80 + +# CHECK: and.ge.f %r6, %r6, 16 +0xc4 0x26 0x2a 0x84 + +# CHECK: and.p.f %r15, %r15, 31 +0xc4 0x27 0xe3 0x97 + +# CHECK: and.n.f %r0, %r0, 0 +0xc4 0x20 0x24 0x80 + +# CHECK: and.vs.f %r6, %r6, 16 +0xc4 0x26 0x27 0x84 + +# CHECK: and.pnz.f %r15, %r15, 31 +0xc4 0x27 0xef 0x97 + # CHECK: asl %r1, %r1, 2 0x40 0x29 0x81 0x00 @@ -105,11 +213,62 @@ # CHECK: sub3.f %fp, %fp, -1 0x99 0x23 0xff 0xbf -# CHECK: rsub.eq %r0, %r0, 30 -0xce 0x20 0xa1 0x07 - # CHECK: rsub.ne %r0, %r0, 31 0xce 0x20 0xe2 0x07 +# CHECK: rsub.eq %r0, %r0, 1 +0xce 0x20 0x61 0x00 + +# CHECK: rsub.lt %r6, %r6, 16 +0xce 0x26 0x2b 0x04 + +# CHECK: rsub.le %r15, %r15, 31 +0xce 0x27 0xec 0x17 + +# CHECK: rsub.gt %r0, %r0, 1 +0xce 0x20 0x69 0x00 + +# CHECK: rsub.ge %r6, %r6, 16 +0xce 0x26 0x2a 0x04 + +# CHECK: rsub.p %r15, %r15, 31 +0xce 0x27 0xe3 0x17 + +# CHECK: rsub.n %r0, %r0, 1 +0xce 0x20 0x64 0x00 + +# CHECK: rsub.vs %r6, %r6, 16 +0xce 0x26 0x27 0x04 + +# CHECK: rsub.pnz %r15, %r15, 31 +0xce 0x27 0xef 0x17 + # CHECK: rsub.ne.f %r0, %r0, 31 0xce 0x20 0xe2 0x87 + +# CHECK: rsub.eq.f %r0, %r0, 1 +0xce 0x20 0x61 0x80 + +# CHECK: rsub.lt.f %r6, %r6, 16 +0xce 0x26 0x2b 0x84 + +# CHECK: rsub.le.f %r15, %r15, 31 +0xce 0x27 0xec 0x97 + +# CHECK: rsub.gt.f %r0, %r0, 1 +0xce 0x20 0x69 0x80 + +# CHECK: rsub.ge.f %r6, %r6, 16 +0xce 0x26 0x2a 0x84 + +# CHECK: rsub.p.f %r15, %r15, 31 +0xce 0x27 0xe3 0x97 + +# CHECK: rsub.n.f %r0, %r0, 1 +0xce 0x20 0x64 0x80 + +# CHECK: rsub.vs.f %r6, %r6, 16 +0xce 0x26 0x27 0x84 + +# CHECK: rsub.pnz.f %r15, %r15, 31 +0xce 0x27 0xef 0x97 diff --git a/llvm/test/MC/Disassembler/ARC/misc.txt b/llvm/test/MC/Disassembler/ARC/misc.txt --- a/llvm/test/MC/Disassembler/ARC/misc.txt +++ b/llvm/test/MC/Disassembler/ARC/misc.txt @@ -22,6 +22,69 @@ # CHECK: mov.ne %r0, 0 0xca 0x20 0x22 0x00 +# CHECK: mov.eq %r0, 0 +0xca 0x20 0x21 0x00 + +# CHECK: mov.lt %r6, 16 +0xca 0x26 0x2b 0x04 + +# CHECK: mov.le %r15, 31 +0xca 0x27 0xec 0x17 + +# CHECK: mov.gt %r0, 0 +0xca 0x20 0x29 0x00 + +# CHECK: mov.ge %r6, 16 +0xca 0x26 0x2a 0x04 + +# CHECK: mov.p %r15, 31 +0xca 0x27 0xe3 0x17 + +# CHECK: mov.n %r0, 0 +0xca 0x20 0x24 0x00 + +# CHECK: mov.vs %r6, 16 +0xca 0x26 0x27 0x04 + +# CHECK: mov.pnz %r15, 31 +0xca 0x27 0xef 0x17 + +# CHECK: mov.f %r0, 0 +0x4a 0x20 0x00 0x80 + +# CHECK: mov.f %r6, 16 +0x4a 0x26 0x00 0x84 + +# CHECK: mov.f %r15, 31 +0x4a 0x27 0xc0 0x97 + +# CHECK: mov.eq.f %r0, 0 +0xca 0x20 0x21 0x80 + +# CHECK: mov.lt.f %r6, 16 +0xca 0x26 0x2b 0x84 + +# CHECK: mov.le.f %r15, 31 +0xca 0x27 0xec 0x97 + +# CHECK: mov.gt.f %r0, 0 +0xca 0x20 0x29 0x80 + +# CHECK: mov.ge.f %r6, 16 +0xca 0x26 0x2a 0x84 + +# CHECK: mov.p.f %r15, 31 +0xca 0x27 0xe3 0x97 + +# CHECK: mov.n.f %r0, 0 +0xca 0x20 0x24 0x80 + +# CHECK: mov.vs.f %r6, 16 +0xca 0x26 0x27 0x84 + +# CHECK: mov.pnz.f %r15, 31 +0xca 0x27 0xef 0x97 + # CHECK: st.aw %fp, [%sp,-4] 0xfc 0x1c 0xc8 0xb6