summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Nacke <kai.nacke@redstar.de>2015-01-27 19:11:28 +0000
committerKai Nacke <kai.nacke@redstar.de>2015-01-27 19:11:28 +0000
commite024539ea0ff3db0c11827e3a0585ea46910ecbc (patch)
tree8d7c2df4069902f4527858af2f953c2d9f5cfd89
parent19d08672844ee7558910d9880555b111fc3c90b3 (diff)
downloadbcm5719-llvm-e024539ea0ff3db0c11827e3a0585ea46910ecbc.tar.gz
bcm5719-llvm-e024539ea0ff3db0c11827e3a0585ea46910ecbc.zip
[mips] Add range checks and transformation to octeon instructions in AsmParser.
This patch adds range checks to the immediate operands of octeon instructions in the AsmParser. Like gas, it applies the following transformations if the immediate is to large: bbit0 $8, 42, foo => bbit032 $8, 10, foo bbit1 $8, 46, foo => bbit132 $8, 14, foo cins $8, $31, 32, 31 => cins32 $8, $31, 0, 31 exts $7, $4, 54, 9 => exts32 $7, $4, 22, 9 Reviewed By: dsanders Differential Revision: http://reviews.llvm.org/D7080 llvm-svn: 227225
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp78
-rw-r--r--llvm/test/MC/Mips/octeon-instructions.s12
2 files changed, 90 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 2e572c124dc..2e698dfbc98 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -382,6 +382,9 @@ public:
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 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
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 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
"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.
diff --git a/llvm/test/MC/Mips/octeon-instructions.s b/llvm/test/MC/Mips/octeon-instructions.s
index e98bbe40f68..34830c0fc6e 100644
--- a/llvm/test/MC/Mips/octeon-instructions.s
+++ b/llvm/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 @@ foo:
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 @@ foo:
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
OpenPOWER on IntegriCloud