Commit 3c645928 authored by danno@chromium.org's avatar danno@chromium.org

MIPS: Don't allow large immediates for certain instructions.

Some instructions can use >16 bit immediates if they represent a <=16 bit signed value.
However some logical instructions (andi, xori, ori, lui) should always treat the immediate value as unsigned.
This patch adds an ASSERT to these places and a minor change to MacroAssembler::li to satisfy this.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9309077
Patch from Daniel Kalmar <kalmard@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10644 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e505a085
...@@ -1245,6 +1245,7 @@ void Assembler::and_(Register rd, Register rs, Register rt) { ...@@ -1245,6 +1245,7 @@ void Assembler::and_(Register rd, Register rs, Register rt) {
void Assembler::andi(Register rt, Register rs, int32_t j) { void Assembler::andi(Register rt, Register rs, int32_t j) {
ASSERT(is_uint16(j));
GenInstrImmediate(ANDI, rs, rt, j); GenInstrImmediate(ANDI, rs, rt, j);
} }
...@@ -1255,6 +1256,7 @@ void Assembler::or_(Register rd, Register rs, Register rt) { ...@@ -1255,6 +1256,7 @@ void Assembler::or_(Register rd, Register rs, Register rt) {
void Assembler::ori(Register rt, Register rs, int32_t j) { void Assembler::ori(Register rt, Register rs, int32_t j) {
ASSERT(is_uint16(j));
GenInstrImmediate(ORI, rs, rt, j); GenInstrImmediate(ORI, rs, rt, j);
} }
...@@ -1265,6 +1267,7 @@ void Assembler::xor_(Register rd, Register rs, Register rt) { ...@@ -1265,6 +1267,7 @@ void Assembler::xor_(Register rd, Register rs, Register rt) {
void Assembler::xori(Register rt, Register rs, int32_t j) { void Assembler::xori(Register rt, Register rs, int32_t j) {
ASSERT(is_uint16(j));
GenInstrImmediate(XORI, rs, rt, j); GenInstrImmediate(XORI, rs, rt, j);
} }
...@@ -1445,6 +1448,7 @@ void Assembler::swr(Register rd, const MemOperand& rs) { ...@@ -1445,6 +1448,7 @@ void Assembler::swr(Register rd, const MemOperand& rs) {
void Assembler::lui(Register rd, int32_t j) { void Assembler::lui(Register rd, int32_t j) {
ASSERT(is_uint16(j));
GenInstrImmediate(LUI, zero_reg, rd, j); GenInstrImmediate(LUI, zero_reg, rd, j);
} }
......
...@@ -771,18 +771,18 @@ void MacroAssembler::li(Register rd, Operand j, bool gen2instr) { ...@@ -771,18 +771,18 @@ void MacroAssembler::li(Register rd, Operand j, bool gen2instr) {
} else if (!(j.imm32_ & kHiMask)) { } else if (!(j.imm32_ & kHiMask)) {
ori(rd, zero_reg, j.imm32_); ori(rd, zero_reg, j.imm32_);
} else if (!(j.imm32_ & kImm16Mask)) { } else if (!(j.imm32_ & kImm16Mask)) {
lui(rd, (j.imm32_ & kHiMask) >> kLuiShift); lui(rd, (j.imm32_ >> kLuiShift) & kImm16Mask);
} else { } else {
lui(rd, (j.imm32_ & kHiMask) >> kLuiShift); lui(rd, (j.imm32_ >> kLuiShift) & kImm16Mask);
ori(rd, rd, (j.imm32_ & kImm16Mask)); ori(rd, rd, (j.imm32_ & kImm16Mask));
} }
} else if (MustUseReg(j.rmode_) || gen2instr) { } else if (MustUseReg(j.rmode_) || gen2instr) {
if (MustUseReg(j.rmode_)) { if (MustUseReg(j.rmode_)) {
RecordRelocInfo(j.rmode_, j.imm32_); RecordRelocInfo(j.rmode_, j.imm32_);
} }
// We need always the same number of instructions as we may need to patch // We always need the same number of instructions as we may need to patch
// this code to load another value which may need 2 instructions to load. // this code to load another value which may need 2 instructions to load.
lui(rd, (j.imm32_ & kHiMask) >> kLuiShift); lui(rd, (j.imm32_ >> kLuiShift) & kImm16Mask);
ori(rd, rd, (j.imm32_ & kImm16Mask)); ori(rd, rd, (j.imm32_ & kImm16Mask));
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment