summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp6
-rw-r--r--llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp12
-rw-r--r--llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp2
-rw-r--r--llvm/test/MC/Disassembler/MSP430/unknown.txt13
-rw-r--r--llvm/test/MC/MSP430/addrmode.s2
-rw-r--r--llvm/test/MC/MSP430/invalid.s1
6 files changed, 33 insertions, 3 deletions
diff --git a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
index 3cc6da2c21a..1ad70ac72c7 100644
--- a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
+++ b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
@@ -497,7 +497,11 @@ bool MSP430AsmParser::ParseOperand(OperandVector &Operands) {
getLexer().Lex(); // Eat '+'
return false;
}
- Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
+ if (Operands.size() > 1) // Emulate @rd in destination position as 0(rd)
+ Operands.push_back(MSP430Operand::CreateMem(RegNo,
+ MCConstantExpr::create(0, getContext()), StartLoc, EndLoc));
+ else
+ Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
return false;
}
case AsmToken::Hash:
diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
index 2a66b4ed7f2..e5da130f9bb 100644
--- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
+++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
@@ -249,6 +249,10 @@ DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size,
case amSymbolic:
case amImmediate:
case amAbsolute:
+ if (Bytes.size() < (Words + 1) * 2) {
+ Size = 2;
+ return DecodeStatus::Fail;
+ }
Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
++Words;
break;
@@ -259,6 +263,10 @@ DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size,
case amIndexed:
case amSymbolic:
case amAbsolute:
+ if (Bytes.size() < (Words + 1) * 2) {
+ Size = 2;
+ return DecodeStatus::Fail;
+ }
Insn |= (uint64_t)support::endian::read16le(Bytes.data() + Words * 2)
<< (Words * 16);
++Words;
@@ -296,6 +304,10 @@ DecodeStatus MSP430Disassembler::getInstructionII(MCInst &MI, uint64_t &Size,
case amSymbolic:
case amImmediate:
case amAbsolute:
+ if (Bytes.size() < (Words + 1) * 2) {
+ Size = 2;
+ return DecodeStatus::Fail;
+ }
Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
++Words;
break;
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
index adf2384f6e9..06f9f307cb1 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
@@ -128,7 +128,7 @@ unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op,
const MCOperand &MO2 = MI.getOperand(Op + 1);
if (MO2.isImm()) {
Offset += 2;
- return (MO2.getImm() << 4) | Reg;
+ return ((unsigned)MO2.getImm() << 4) | Reg;
}
assert(MO2.isExpr() && "Expr operand expected");
diff --git a/llvm/test/MC/Disassembler/MSP430/unknown.txt b/llvm/test/MC/Disassembler/MSP430/unknown.txt
new file mode 100644
index 00000000000..d7e680b98ae
--- /dev/null
+++ b/llvm/test/MC/Disassembler/MSP430/unknown.txt
@@ -0,0 +1,13 @@
+# RUN: not llvm-mc -disassemble -triple=msp430 %s 2>&1 | FileCheck %s
+
+# This should not decode as 'and.b @r15+, (0)r1' [0xf1,0xff,0x00,0x00]
+[0xf1 0xff]
+# CHECK: warning: invalid instruction encoding
+
+# This should not decode as 'add 6(r7), 6(r5)' [0x95 0x57 0x06 0x00 0x06 0x00]
+[0x95 0x57 0x06 0x00]
+# CHECK: warning: invalid instruction encoding
+
+# This should not decode as 'call 6(r7)' [0x97 0x12 0x06 0x00]
+[0x97 0x12]
+# CHECK: warning: invalid instruction encoding
diff --git a/llvm/test/MC/MSP430/addrmode.s b/llvm/test/MC/MSP430/addrmode.s
index 7e389b6a50f..c787e683aea 100644
--- a/llvm/test/MC/MSP430/addrmode.s
+++ b/llvm/test/MC/MSP430/addrmode.s
@@ -21,11 +21,13 @@ foo:
mov #42, 12(r15)
mov #42, &disp
mov disp, disp+2
+ mov r7, @r15
; CHECK: mov #42, r15 ; encoding: [0x3f,0x40,0x2a,0x00]
; CHECK: mov #42, 12(r15) ; encoding: [0xbf,0x40,0x2a,0x00,0x0c,0x00]
; CHECK: mov #42, &disp ; encoding: [0xb2,0x40,0x2a,0x00,A,A]
; CHECK: mov disp, disp+2 ; encoding: [0x90,0x40,A,A,B,B]
+; CHECK: mov r7, 0(r15) ; encoding: [0x8f,0x47,0x00,0x00]
add r7, r8
add 6(r7), r8
diff --git a/llvm/test/MC/MSP430/invalid.s b/llvm/test/MC/MSP430/invalid.s
index 2815b520dd5..ce686bd83f1 100644
--- a/llvm/test/MC/MSP430/invalid.s
+++ b/llvm/test/MC/MSP430/invalid.s
@@ -4,7 +4,6 @@ foo:
mov r7 ; CHECK: :[[@LINE]]:3: error: too few operands for instruction
;; invalid destination addressing modes
- mov r7, @r15 ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction
mov r7, @r15+ ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction
mov r7, #0 ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction
mov r7, #123 ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction
OpenPOWER on IntegriCloud