diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index 9cbece93a3c4..901560c5c97c 100644 --- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -68,8 +68,7 @@ class SparcAsmParser : public MCTargetAsmParser { StringRef Name); OperandMatchResultTy - parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false, - bool createTokenForFCC = true); + parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false); OperandMatchResultTy parseBranchModifiers(SmallVectorImpl &Operands); @@ -633,9 +632,7 @@ parseOperand(SmallVectorImpl &Operands, SparcOperand *Op = 0; - bool createTokenForFCC = !(Mnemonic == "fcmps" || Mnemonic == "fcmpd" - || Mnemonic == "fcmpq"); - ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"), createTokenForFCC); + ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call")); if (ResTy != MatchOperand_Success || !Op) return MatchOperand_ParseFail; @@ -646,8 +643,7 @@ parseOperand(SmallVectorImpl &Operands, } SparcAsmParser::OperandMatchResultTy -SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall, - bool createTokenForFCC) +SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall) { SMLoc S = Parser.getTok().getLoc(); @@ -680,13 +676,6 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall, else Op = SparcOperand::CreateToken("%icc", S); break; - - case Sparc::FCC0: - if (createTokenForFCC) { - assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet"); - Op = SparcOperand::CreateToken("%fcc0", S); - break; - } } break; } diff --git a/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp index 66b4b519f7ef..7a8a66341cec 100644 --- a/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp +++ b/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp @@ -146,11 +146,12 @@ void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum, case SP::BPFCCA: case SP::BPFCCNT: case SP::BPFCCANT: - case SP::MOVFCCrr: - case SP::MOVFCCri: - case SP::FMOVS_FCC: - case SP::FMOVD_FCC: - case SP::FMOVQ_FCC: // Make sure CC is a fp conditional flag. + case SP::MOVFCCrr: case SP::V9MOVFCCrr: + case SP::MOVFCCri: case SP::V9MOVFCCri: + case SP::FMOVS_FCC: case SP::V9FMOVS_FCC: + case SP::FMOVD_FCC: case SP::V9FMOVD_FCC: + case SP::FMOVQ_FCC: case SP::V9FMOVQ_FCC: + // Make sure CC is a fp conditional flag. CC = (CC < 16) ? (CC + 16) : CC; break; } diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td index 93a6c24a0838..dc35544daa35 100644 --- a/llvm/lib/Target/Sparc/SparcInstrAliases.td +++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td @@ -13,31 +13,52 @@ // Instruction aliases for conditional moves. // mov rs2, rd -multiclass cond_mov_alias { - // mov (%icc|%xcc|%fcc0), rs2, rd + // mov (%icc|%xcc), rs2, rd def : InstAlias; - // mov (%icc|%xcc|%fcc0), simm11, rd + // mov (%icc|%xcc), simm11, rd def : InstAlias; - // fmovs (%icc|%xcc|%fcc0), $rs2, $rd + // fmovs (%icc|%xcc), $rs2, $rd def : InstAlias; - // fmovd (%icc|%xcc|%fcc0), $rs2, $rd + // fmovd (%icc|%xcc), $rs2, $rd def : InstAlias; } +// mov rs2, rd +multiclass fpcond_mov_alias { + + // mov %fcc[0-3], rs2, rd + def : InstAlias; + + // mov %fcc[0-3], simm11, rd + def : InstAlias; + + // fmovs %fcc[0-3], $rs2, $rd + def : InstAlias; + + // fmovd %fcc[0-3], $rs2, $rd + def : InstAlias; +} // Instruction aliases for integer conditional branches and moves. multiclass int_cond_alias { @@ -99,11 +120,11 @@ multiclass int_cond_alias { (BPXCCANT brtarget:$imm, condVal)>, Requires<[Is64Bit]>; - defm : cond_mov_alias, Requires<[HasV9]>; - defm : cond_mov_alias, Requires<[Is64Bit]>; @@ -130,36 +151,42 @@ multiclass fp_cond_alias { (FBCONDA brtarget:$imm, condVal), 0>; // fb %fcc0, $imm - def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9]>; // fb,pt %fcc0, $imm - def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9]>; // fb,a %fcc0, $imm - def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9]>; // fb,a,pt %fcc0, $imm - def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9]>; // fb,pn %fcc0, $imm - def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9]>; // fb,a,pn %fcc0, $imm - def : InstAlias, Requires<[HasV9]>; + def : InstAlias, Requires<[HasV9]>; - defm : cond_mov_alias, Requires<[HasV9]>; + defm : fpcond_mov_alias, Requires<[HasV9]>; // fmovq %fcc0, $rs2, $rd - def : InstAlias, + def : InstAlias, Requires<[HasV9, HasHardQuad]>; } diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index a27e6abf2bc8..b4d8ba55fd14 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -1019,7 +1019,7 @@ let Predicates = [HasV9] in { Requires<[HasHardQuad]>; } -// Floating-point compare instruction with %fcc0-%fcc1 +// Floating-point compare instruction with %fcc0-%fcc3. def V9FCMPS : F3_3c<2, 0b110101, 0b001010001, (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), "fcmps $rd, $rs1, $rs2", []>; @@ -1031,6 +1031,34 @@ def V9FCMPQ : F3_3c<2, 0b110101, 0b001010011, "fcmpq $rd, $rs1, $rs2", []>, Requires<[HasHardQuad]>; +// Floating point conditional move instrucitons with %fcc0-%fcc3. +let Predicates = [HasV9] in { + let Constraints = "$f = $rd", intcc = 0 in { + def V9MOVFCCrr + : F4_1<0b101100, (outs IntRegs:$rd), + (ins FCCRegs:$cc, IntRegs:$rs2, IntRegs:$f, CCOp:$cond), + "mov$cond $cc, $rs2, $rd", []>; + def V9MOVFCCri + : F4_2<0b101100, (outs IntRegs:$rd), + (ins FCCRegs:$cc, i32imm:$simm11, IntRegs:$f, CCOp:$cond), + "mov$cond $cc, $simm11, $rd", []>; + def V9FMOVS_FCC + : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), + (ins FCCRegs:$opf_cc, FPRegs:$rs2, FPRegs:$f, CCOp:$cond), + "fmovs$cond $opf_cc, $rs2, $rd", []>; + def V9FMOVD_FCC + : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), + (ins FCCRegs:$opf_cc, DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), + "fmovd$cond $opf_cc, $rs2, $rd", []>; + def V9FMOVQ_FCC + : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), + (ins FCCRegs:$opf_cc, QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), + "fmovq$cond $opf_cc, $rs2, $rd", []>, + Requires<[HasHardQuad]>; + } // Constraints = "$f = $rd", ... +} // let Predicates = [hasV9] + + // POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear // the top 32-bits before using it. To do this clearing, we use a SRLri X,0. let rs1 = 0 in diff --git a/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s b/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s index 0ea7716afb71..7d6d98e20fa5 100644 --- a/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s +++ b/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s @@ -146,20 +146,20 @@ movo %fcc0, %g1, %g2 - ! CHECK fmovsne %icc, %f1, %f2 ! encoding: [0x85,0xaa,0x60,0x21] - ! CHECK fmovse %icc, %f1, %f2 ! encoding: [0x85,0xa8,0x60,0x21] - ! CHECK fmovsg %icc, %f1, %f2 ! encoding: [0x85,0xaa,0xa0,0x21] - ! CHECK fmovsle %icc, %f1, %f2 ! encoding: [0x85,0xa8,0xa0,0x21] - ! CHECK fmovsge %icc, %f1, %f2 ! encoding: [0x85,0xaa,0xe0,0x21] - ! CHECK fmovsl %icc, %f1, %f2 ! encoding: [0x85,0xa8,0xe0,0x21] - ! CHECK fmovsgu %icc, %f1, %f2 ! encoding: [0x85,0xab,0x20,0x21] - ! CHECK fmovsleu %icc, %f1, %f2 ! encoding: [0x85,0xa9,0x20,0x21] - ! CHECK fmovscc %icc, %f1, %f2 ! encoding: [0x85,0xab,0x60,0x21] - ! CHECK fmovscs %icc, %f1, %f2 ! encoding: [0x85,0xa9,0x60,0x21] - ! CHECK fmovspos %icc, %f1, %f2 ! encoding: [0x85,0xab,0xa0,0x21] - ! CHECK fmovsneg %icc, %f1, %f2 ! encoding: [0x85,0xa9,0xa0,0x21] - ! CHECK fmovsvc %icc, %f1, %f2 ! encoding: [0x85,0xab,0xe0,0x21] - ! CHECK fmovsvs %icc, %f1, %f2 ! encoding: [0x85,0xa9,0xe0,0x21] + ! CHECK: fmovsne %icc, %f1, %f2 ! encoding: [0x85,0xaa,0x60,0x21] + ! CHECK: fmovse %icc, %f1, %f2 ! encoding: [0x85,0xa8,0x60,0x21] + ! CHECK: fmovsg %icc, %f1, %f2 ! encoding: [0x85,0xaa,0xa0,0x21] + ! CHECK: fmovsle %icc, %f1, %f2 ! encoding: [0x85,0xa8,0xa0,0x21] + ! CHECK: fmovsge %icc, %f1, %f2 ! encoding: [0x85,0xaa,0xe0,0x21] + ! CHECK: fmovsl %icc, %f1, %f2 ! encoding: [0x85,0xa8,0xe0,0x21] + ! CHECK: fmovsgu %icc, %f1, %f2 ! encoding: [0x85,0xab,0x20,0x21] + ! CHECK: fmovsleu %icc, %f1, %f2 ! encoding: [0x85,0xa9,0x20,0x21] + ! CHECK: fmovscc %icc, %f1, %f2 ! encoding: [0x85,0xab,0x60,0x21] + ! CHECK: fmovscs %icc, %f1, %f2 ! encoding: [0x85,0xa9,0x60,0x21] + ! CHECK: fmovspos %icc, %f1, %f2 ! encoding: [0x85,0xab,0xa0,0x21] + ! CHECK: fmovsneg %icc, %f1, %f2 ! encoding: [0x85,0xa9,0xa0,0x21] + ! CHECK: fmovsvc %icc, %f1, %f2 ! encoding: [0x85,0xab,0xe0,0x21] + ! CHECK: fmovsvs %icc, %f1, %f2 ! encoding: [0x85,0xa9,0xe0,0x21] fmovsne %icc, %f1, %f2 fmovse %icc, %f1, %f2 fmovsg %icc, %f1, %f2 @@ -175,20 +175,20 @@ fmovsvc %icc, %f1, %f2 fmovsvs %icc, %f1, %f2 - ! CHECK fmovsne %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0x70,0x21] - ! CHECK fmovse %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0x70,0x21] - ! CHECK fmovsg %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0xb0,0x21] - ! CHECK fmovsle %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0xb0,0x21] - ! CHECK fmovsge %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0xf0,0x21] - ! CHECK fmovsl %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0xf0,0x21] - ! CHECK fmovsgu %xcc, %f1, %f2 ! encoding: [0x85,0xab,0x30,0x21] - ! CHECK fmovsleu %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0x30,0x21] - ! CHECK fmovscc %xcc, %f1, %f2 ! encoding: [0x85,0xab,0x70,0x21] - ! CHECK fmovscs %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0x70,0x21] - ! CHECK fmovspos %xcc, %f1, %f2 ! encoding: [0x85,0xab,0xb0,0x21] - ! CHECK fmovsneg %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0xb0,0x21] - ! CHECK fmovsvc %xcc, %f1, %f2 ! encoding: [0x85,0xab,0xf0,0x21] - ! CHECK fmovsvs %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0xf0,0x21] + ! CHECK: fmovsne %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0x70,0x21] + ! CHECK: fmovse %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0x70,0x21] + ! CHECK: fmovsg %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0xb0,0x21] + ! CHECK: fmovsle %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0xb0,0x21] + ! CHECK: fmovsge %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0xf0,0x21] + ! CHECK: fmovsl %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0xf0,0x21] + ! CHECK: fmovsgu %xcc, %f1, %f2 ! encoding: [0x85,0xab,0x30,0x21] + ! CHECK: fmovsleu %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0x30,0x21] + ! CHECK: fmovscc %xcc, %f1, %f2 ! encoding: [0x85,0xab,0x70,0x21] + ! CHECK: fmovscs %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0x70,0x21] + ! CHECK: fmovspos %xcc, %f1, %f2 ! encoding: [0x85,0xab,0xb0,0x21] + ! CHECK: fmovsneg %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0xb0,0x21] + ! CHECK: fmovsvc %xcc, %f1, %f2 ! encoding: [0x85,0xab,0xf0,0x21] + ! CHECK: fmovsvs %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0xf0,0x21] fmovsne %xcc, %f1, %f2 fmovse %xcc, %f1, %f2 fmovsg %xcc, %f1, %f2 @@ -204,20 +204,20 @@ fmovsvc %xcc, %f1, %f2 fmovsvs %xcc, %f1, %f2 - ! CHECK fmovsu %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0xc0,0x21] - ! CHECK fmovsg %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x80,0x21] - ! CHECK fmovsug %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x40,0x21] - ! CHECK fmovsl %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x00,0x21] - ! CHECK fmovsul %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0xc0,0x21] - ! CHECK fmovslg %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0x80,0x21] - ! CHECK fmovsne %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0x40,0x21] - ! CHECK fmovse %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0x40,0x21] - ! CHECK fmovsue %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0x80,0x21] - ! CHECK fmovsge %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0xc0,0x21] - ! CHECK fmovsuge %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x00,0x21] - ! CHECK fmovsle %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x40,0x21] - ! CHECK fmovsule %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x80,0x21] - ! CHECK fmovso %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0xc0,0x21] + ! CHECK: fmovsu %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0xc0,0x21] + ! CHECK: fmovsg %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x80,0x21] + ! CHECK: fmovsug %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x40,0x21] + ! CHECK: fmovsl %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x00,0x21] + ! CHECK: fmovsul %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0xc0,0x21] + ! CHECK: fmovslg %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0x80,0x21] + ! CHECK: fmovsne %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0x40,0x21] + ! CHECK: fmovse %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0x40,0x21] + ! CHECK: fmovsue %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0x80,0x21] + ! CHECK: fmovsge %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0xc0,0x21] + ! CHECK: fmovsuge %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x00,0x21] + ! CHECK: fmovsle %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x40,0x21] + ! CHECK: fmovsule %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x80,0x21] + ! CHECK: fmovso %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0xc0,0x21] fmovsu %fcc0, %f1, %f2 fmovsg %fcc0, %f1, %f2 fmovsug %fcc0, %f1, %f2 @@ -1111,3 +1111,28 @@ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19 fbo,a,pn %fcc0, .BB0 + ! CHECK: movu %fcc1, %g1, %g2 ! encoding: [0x85,0x61,0xc8,0x01] + movu %fcc1, %g1, %g2 + + ! CHECK: fmovsg %fcc2, %f1, %f2 ! encoding: [0x85,0xa9,0x90,0x21] + fmovsg %fcc2, %f1, %f2 + + ! CHECK: fbug %fcc3, .BB0 ! encoding: [0x0b,0b01111AAA,A,A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19 + fbug %fcc3, .BB0 + + ! CHECK: fbu %fcc3, .BB0 ! encoding: [0x0f,0b01111AAA,A,A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19 + fbu,pt %fcc3, .BB0 + + ! CHECK: fbl,a %fcc3, .BB0 ! encoding: [0x29,0b01111AAA,A,A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19 + fbl,a %fcc3, .BB0 + + ! CHECK: fbue,pn %fcc3, .BB0 ! encoding: [0x15,0b01110AAA,A,A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19 + fbue,pn %fcc3, .BB0 + + ! CHECK: fbne,a,pn %fcc3, .BB0 ! encoding: [0x23,0b01110AAA,A,A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19 + fbne,a,pn %fcc3, .BB0