Index: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -382,6 +382,9 @@ bool hasMips64r6() const { return (STI.getFeatureBits() & Mips::FeatureMips64r6); } + bool hasCnMips() const { + return (STI.getFeatureBits() & Mips::FeatureCnMips); + } bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); } bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); } bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); } @@ -1168,6 +1171,13 @@ switch (Opcode) { default: break; + case Mips::BBIT0: + case Mips::BBIT032: + case Mips::BBIT1: + case Mips::BBIT132: + assert(hasCnMips() && "instruction only valid for octeon cpus"); + // Fall through + case Mips::BEQ: case Mips::BNE: case Mips::BEQ_MM: @@ -1230,6 +1240,74 @@ "nop instruction"); } + if (hasCnMips()) { + const unsigned Opcode = Inst.getOpcode(); + MCOperand Opnd; + int Imm; + + switch (Opcode) { + default: + break; + + case Mips::BBIT0: + case Mips::BBIT032: + case Mips::BBIT1: + case Mips::BBIT132: + assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); + // The offset is handled above + Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 || + Opcode == Mips::BBIT1 ? 63 : 31)) + return Error(IDLoc, "immediate operand value out of range"); + if (Imm > 31) { + Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032 + : Mips::BBIT132); + Inst.getOperand(1).setImm(Imm - 32); + } + break; + + case Mips::CINS: + case Mips::CINS32: + case Mips::EXTS: + case Mips::EXTS32: + assert(MCID.getNumOperands() == 4 && "unexpected number of operands"); + // Check length + Opnd = Inst.getOperand(3); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 0 || Imm > 31) + return Error(IDLoc, "immediate operand value out of range"); + // Check position + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 0 || Imm > (Opcode == Mips::CINS || + Opcode == Mips::EXTS ? 63 : 31)) + return Error(IDLoc, "immediate operand value out of range"); + if (Imm > 31) { + Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32); + Inst.getOperand(2).setImm(Imm - 32); + } + break; + + case Mips::SEQi: + case Mips::SNEi: + assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (!isInt<10>(Imm)) + return Error(IDLoc, "immediate operand value out of range"); + break; + } + } + if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) { // If this instruction has a delay slot and .set reorder is active, // emit a NOP after it. Index: llvm/trunk/test/MC/Mips/octeon-instructions.s =================================================================== --- llvm/trunk/test/MC/Mips/octeon-instructions.s +++ llvm/trunk/test/MC/Mips/octeon-instructions.s @@ -5,12 +5,16 @@ # CHECK: baddu $2, $2, $3 # encoding: [0x70,0x43,0x10,0x28] # CHECK: bbit0 $19, 22, foo # encoding: [0xca,0x76,A,A] # CHECK: bbit032 $fp, 11, foo # encoding: [0xdb,0xcb,A,A] +# CHECK: bbit032 $8, 10, foo # encoding: [0xd9,0x0a,A,A] # CHECK: bbit1 $3, 31, foo # encoding: [0xe8,0x7f,A,A] # CHECK: bbit132 $24, 10, foo # encoding: [0xfb,0x0a,A,A] +# CHECK: bbit132 $14, 14, foo # encoding: [0xf9,0xce,A,A] # CHECK: cins $25, $10, 22, 2 # encoding: [0x71,0x59,0x15,0xb2] # CHECK: cins $9, $9, 17, 29 # encoding: [0x71,0x29,0xec,0x72] # CHECK: cins32 $15, $2, 18, 8 # encoding: [0x70,0x4f,0x44,0xb3] # CHECK: cins32 $22, $22, 9, 22 # encoding: [0x72,0xd6,0xb2,0x73] +# CHECK: cins32 $24, $ra, 0, 31 # encoding: [0x73,0xf8,0xf8,0x33] +# CHECK: cins32 $15, $15, 5, 5 # encoding: [0x71,0xef,0x29,0x73] # CHECK: dmul $9, $6, $7 # encoding: [0x70,0xc7,0x48,0x03] # CHECK: dmul $19, $24, $25 # encoding: [0x73,0x19,0x98,0x03] # CHECK: dmul $9, $9, $6 # encoding: [0x71,0x26,0x48,0x03] @@ -22,6 +26,8 @@ # CHECK: exts $15, $15, 17, 6 # encoding: [0x71,0xef,0x34,0x7a] # CHECK: exts32 $4, $13, 10, 8 # encoding: [0x71,0xa4,0x42,0xbb] # CHECK: exts32 $15, $15, 11, 20 # encoding: [0x71,0xef,0xa2,0xfb] +# CHECK: exts32 $7, $4, 22, 9 # encoding: [0x70,0x87,0x4d,0xbb] +# CHECK: exts32 $25, $25, 5, 25 # encoding: [0x73,0x39,0xc9,0x7b] # CHECK: mtm0 $15 # encoding: [0x71,0xe0,0x00,0x08] # CHECK: mtm1 $16 # encoding: [0x72,0x00,0x00,0x0c] # CHECK: mtm2 $17 # encoding: [0x72,0x20,0x00,0x0d] @@ -56,12 +62,16 @@ baddu $2, $3 bbit0 $19, 22, foo bbit032 $30, 11, foo + bbit0 $8, 42, foo bbit1 $3, 31, foo bbit132 $24, 10, foo + bbit1 $14, 46, foo cins $25, $10, 22, 2 cins $9, 17, 29 cins32 $15, $2, 18, 8 cins32 $22, 9, 22 + cins $24, $31, 32, 31 + cins $15, 37, 5 dmul $9, $6, $7 dmul $19, $24, $25 dmul $9, $6 @@ -73,6 +83,8 @@ exts $15, 17, 6 exts32 $4, $13, 10, 8 exts32 $15, 11, 20 + exts $7, $4, 54, 9 + exts $25, 37, 25 mtm0 $15 mtm1 $16 mtm2 $17