* [Qemu-devel] New emulator: MIPS-user
@ 2005-02-09 18:49 McMullan, Jason
2005-02-09 22:02 ` J. Mayer
0 siblings, 1 reply; 6+ messages in thread
From: McMullan, Jason @ 2005-02-09 18:49 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1.1: Type: text/plain, Size: 647 bytes --]
So, I'm working on converting my pure-emulation mips-user emulator
( http://www.sourceforge.net/projects/gehail ) to QEMU's dynamic
code generator system, and I was wondering if there's a document
that describes the general architecture, and:
a) What PARAM1..PARAM3 are, and where and where not to use them.
b) The proper way to use JUMP_TB()
c) The rules for creating a proper op.c file
d) etc.
Attached is the 'mips64.spec' file I'll be using to automatically
generate my op.c and translate.c, just so you know that there's real
code behind this.
--
Jason McMullan <jason.mcmullan@timesys.com>
TimeSys Corporation
[-- Attachment #1.2: mips64.spec --]
[-- Type: text/plain, Size: 43495 bytes --]
/* ABS.fmt Abs - Floating Point Absolute Value
*/
010001 fmt(5) 00000 fs(5) fd(5) 000101:
StoreFPR(fd, fmt, float_abs(ValueFPR(fs, fmt)));
/* ADD Add Word
*/
000000 rs(5) rt(5) rd(5) 00000 100000:
uint64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt]) ) {
UNPREDICTABLE;
}
temp = (bit(GPR[rs],31) << 32) | GPR[rs];
temp += (bit(GPR[rt],31) << 32) | GPR[rt];
if (bit(temp,32) != bit(temp,31)) {
SignalException(IntegerOverflow);
} else {
GPR[rd] = sign_extend(temp, 32);
}
/* ADDI Add immediate
*/
001000 rs(5) rt(5) immediate(16):
uint64_t temp;
if (NotWordValue(GPR[rs])) {
UNPREDICTABLE;
}
temp = (bit(GPR[rs],31) << 32) | GPR[rs];
temp += sign_extend(immediate,16);
if (bit(temp,32) != bit(temp,31)) {
SignalException(IntegerOverflow);
} else {
GPR[rt] = sign_extend(temp, 32);
}
/* ADDIU Add immediate, unsigned
*/
001001 rs(5) rt(5) immediate(16):
uint64_t temp;
if (NotWordValue(GPR[rs])) {
UNPREDICTABLE;
}
temp = GPR[rs] + sign_extend(immediate, 16);
GPR[rt] = sign_extend(temp, 32);
/* ADDU Add unsigned word
*/
000000 rs(5) rt(5) rd(5) 00000 100001:
uint64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = GPR[rs] + GPR[rt];
GPR[rd] = sign_extend(temp, 32);
/* ALNV.PS Floating point align
*/
010011 rs(5) ft(5) fs(5) fd(5) 011110:
if (bits(GPR[rs],0,2) == 0) {
StoreFPR(fd, PS, ValueFPR(fd, PS));
} else if (bits(GPR[rs],0,2) != 4) {
UNPREDICTABLE;
} else if (BigEndianCPU) {
StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),0,31) << 32) | bits(ValueFPR(ft, PS), 32, 63));
} else {
StoreFPR(fd, PS, (bits(ValueFPR(ft, PS),0,31) << 32) | bits(ValueFPR(fs, PS), 32, 63));
}
/* AND And
*/
000000 rs(5) rt(5) rd(5) 00000 100100:
GPR[rd] = GPR[rs] & GPR[rt];
/* ANDI And Immediate
*/
001100 rs(5) rt(5) immediate(16):
GPR[rt] = GPR[rs] & zero_extend(immediate, 16);
/* B Unconditional branch
*/
000100 00000 00000 offset(16):
uint64_t target_offset;
/* I: */ target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ PC = PC + target_offset - 4;
/* BAL Branch and Link
*/
000001 00000 10001 offset(16):
uint64_t target_offset;
/* I: */ target_offset = sign_extend(offset << 2, 18);
GPR[31] = PC + 4;
NextInstruction();
/* I+1: */ PC = PC + target_offset - 4;
/* BC1F/T Branch on FP False/True
*/
010001 01000 cc(3) 0 tf(1) offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition=FPConditionCode(cc) == tf;
target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BC1F/TL Branch on FP False/True Likely
*/
010001 01000 cc(3) 1 tf(1) offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition=FPConditionCode(cc) == tf;
target_offset = sign_extend(offset << 2, 18);
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BC2F/T Branch on COP2 False/True
*/
010010 01000 cc(3) 0 tf(1) offset(16):
SignalException(Unimplemented);
/* BC2F/TL Branch on COP2 False/True Likely
*/
010001 01000 cc(3) 1 tf(1) offset(16):
SignalException(Unimplemented);
/* BEQ Branch on Equal
*/
000100 rs(5) rt(5) offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = (GPR[rs] == GPR[rt]);
target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BEQL branch on Equal Likely
*/
010100 rs(5) rt(5) offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = (GPR[rs] == GPR[rt]);
target_offset = sign_extend(offset << 2, 18);
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BGEZ Branch on Equal or Greater Than Zero
*/
000001 rs(5) 00001 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] >= 0);
target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BGEZL Branch on Equal or Greater Than Zero Likely
*/
000001 rs(5) 00011 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] >= 0);
target_offset = sign_extend(offset << 2, 18);
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BGEZAL Branch on greater Than or Equal to Zero and Link
*/
000001 rs(5) 10001 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] >= 0);
target_offset = sign_extend(offset << 2, 18);
GPR[31] = PC + 4;
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BGEZALL Branch on greater Than or Equal to Zero and Link Likely
*/
000001 rs(5) 10011 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] >= 0);
target_offset = sign_extend(offset << 2, 18);
GPR[31] = PC + 4;
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BGTZ Branch on Greater Than Zero
*/
000111 rs(5) 00000 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] > 0);
target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BGTZL Branch on Greater Than Zero Likely
*/
010111 rs(5) 00000 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] > 0);
target_offset = sign_extend(offset << 2, 18);
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BLEZ Branch on Less Than or Equal to Zero
*/
000110 rs(5) 00000 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] <= 0);
target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BLEZL Branch on Less Than or Equal to Zero Likely
*/
010110 rs(5) 00000 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] <= 0);
target_offset = sign_extend(offset << 2, 18);
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BLTZ Branch on Less Than Zero
*/
000001 rs(5) 00000 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] < 0);
target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BLTZL Branch on Less Than Zero Likely
*/
000001 rs(5) 00010 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] < 0);
target_offset = sign_extend(offset << 2, 18);
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BLTZAL Branch on Less Than Zero and Link
*/
000001 rs(5) 10000 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] < 0);
target_offset = sign_extend(offset << 2, 18);
GPR[31] = PC + 4;
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BLTZALL Branch on Less Than Zero and Link Likely
*/
000001 rs(5) 10010 offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = ((int64_t)GPR[rs] < 0);
target_offset = sign_extend(offset << 2, 18);
GPR[31] = PC + 4;
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BNE Branch on Not Equal
*/
000101 rs(5) rt(5) offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = (GPR[rs] != GPR[rt]);
target_offset = sign_extend(offset << 2, 18);
NextInstruction();
/* I+1: */ if (condition) {
PC = PC + target_offset - 4;
}
/* BNEL Branch on Not Equal Likely
*/
010101 rs(5) rt(5) offset(16):
uint64_t target_offset;
int condition;
/* I: */ condition = (GPR[rs] != GPR[rt]);
target_offset = sign_extend(offset << 2, 18);
/* I+1: */ if (condition) {
NextInstruction();
PC = PC + target_offset - 4;
}
/* BREAK Breakpoint
*/
000000 code(20) 001101:
SignalException(Breakpoint);
/* C.cond.fmt Floating Point Compare
*/
010001 fmt(5) ft(5) fs(5) cc(3) 0 0 11 cond(4):
int less, equal, unordered, condition;
if (SNaN(ValueFPR(fs, fmt)) || SNaN(ValueFPR(ft, fmt)) ||
QNaN(ValueFPR(fs, fmt)) || QNaN(ValueFPR(ft, fmt))) {
less = 0;
equal = 0;
unordered = 1;
if (SNaN(ValueFPR(fs,fmt)) || SNaN(ValueFPR(ft, fmt)) ||
(bit(cond,3) && (QNaN(ValueFPR(fs, fmt) || QNaN(ValueFPR(ft, fmt)))))) {
SignalException(InvalidOperation);
}
} else {
less = float_less_than(ValueFPR(fs, fmt),ValueFPR(ft, fmt));
equal = float_equal_to(ValueFPR(fs, fmt),ValueFPR(ft, fmt));
unordered = 0;
}
condition = (bit(cond,2) && less) || (bit(cond,1) && equal) ||
(bit(cond,0) && unordered);
SetFPConditionCode(condition);
/* CACHE Perform Cache Operation
*/
101111 base(5) op(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
/* (pAddr, uncached) = AddressTranslation(vAddr, DataReadReference); */
/* CacheOp(op, vAddr, pAddr); */
/* CEIL.L.fmt Fixed Point Ceiling Convert to Long Fixed Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 001010:
StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L));
/* CEIL.W.fmt Floating Point Ceiling Convert to Word Fixed Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 001110:
StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W));
/* CFC1 Move Control Word From Floating Point
* This has to be before ADD.fmt.
*/
010001 00010 rt(5) fs(5) 00000 000000:
uint32_t temp;
if (fs == 0) {
temp = FIR;
} else if (fs == 25) {
temp = (bits(FCSR,25,31) << 1) | bit(FCSR,23);
} else if (fs == 26) {
temp = (bits(FCSR,12,17) << 12) | (bits(FCSR,2,6) << 2);
} else if (fs == 28) {
temp = (bits(FCSR,7,11) << 7) | (bit(FCSR,24) << 2) | bits(FCSR,0,1);
} else if (fs == 31) {
temp = FCSR;
} else {
temp = 0;
}
GPR[rt] = sign_extend(temp, 32);
/* CFC2 Move Control Word From Coprocessor 2
*/
010010 00010 rt(5) Impl(16):
/* GPR[rt] = sign_extend(CP2CCR[Impl], 32); */
GPR[rt] = 0;
/* CLO/Z Count Leading Ones/Zeros in Word
*/
011100 rs(5) rt(5) rd(5) 00000 10000 one_zero(1):
int temp, i;
if (NotWordValue(GPR[rs])) {
UNPREDICTABLE;
}
temp = 32;
for (i = 31; i >= 0; i--) {
if (bit(GPR[rs],i) != one_zero) {
temp = 31 - i;
break;
}
}
GPR[rd] = temp;
/* COP2 Coprocessor Operation to Coprocessor 2
*/
010010 1 cofun(25):
SignalException(Unimplemented);
/* CTC1 Move Control Word To Floating Point
*/
010001 00110 rt(5) fs(5) 00000 000000:
uint32_t temp;
temp=bits(GPR[rt],0,31);
if (fs == 25) {
if (bits(temp,8,31) != 0) {
UNPREDICTABLE;
} else {
FCSR = (bits(temp,1,7) << 25) | (bit(FCSR,24) << 24) | (bit(temp,0) << 23) | bits(FCSR,0,22);
}
} else if (fs == 26) {
if (bits(temp,18,22) != 0) {
UNPREDICTABLE;
} else {
FCSR = (bits(FCSR,18,31) << 18) | (bits(temp,12,17) << 12) | (bits(FCSR,7,11) << 7) | (bits(temp,2,6) << 2) | bits(FCSR,0,1);
}
} else if (fs == 28) {
if (bits(temp,18,22) != 0) {
UNPREDICTABLE;
} else {
FCSR = (bits(FCSR,25,31) << 25) | (bit(temp,2) << 24) | (bits(FCSR,12,23) << 12) | (bits(temp,7,11) << 7) | (bits(FCSR,2,6) << 2) | bits(temp,0,1);
}
} else if (fs == 31) {
if (bits(temp,18,22) != 0) {
UNPREDICTABLE;
} else {
FCSR = temp;
}
} else {
UNPREDICTABLE;
}
/* CTC2 Move Control Word to Coprocessor 2
*/
010010 00110 rt(5) Impl(16):
/* CP2CCR[Impl] = bits(GPR[rt],0,31); */
/* CVT.D.fmt Floating Point Convert to Double Floating Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 100001:
StoreFPR(fd, D, ConvertFmt(ValueFPR(fs, fmt), fmt, D));
/* CVT.L.fmt Floating Point Convert to Long Fixed Format
*/
010001 fmt(5) 00000 fs(5) fd(5) 100101:
StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L));
/* CVT.PS.S Floating Point Convert Pair to Paired Single
*/
010001 10000 ft(5) fs(5) fd(5) 100110:
StoreFPR(fd, S, (ValueFPR(fs, S) << 32) | ValueFPR(ft, S));
/* CVT.S.fmt Floating Point Convert to Single Floating Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 100000:
StoreFPR(fd, S, ConvertFmt(ValueFPR(fs, fmt), fmt, S));
/* CVT.S.PL Floating Point Convert Pair Lower to Single Floating Point
*/
010001 10110 00000 fs(5) fd(5) 101000:
StoreFPR(fd, S, ConvertFmt(ValueFPR(fs, PS), PL, S));
/* CVT.S.PU Floating Point Convert Pair Upper to Single Floating Point
*/
010001 10110 00000 fs(5) fd(5) 100000:
StoreFPR(fd, S, ConvertFmt(ValueFPR(fs, PS), PU, S));
/* CVT.W.fmt Floating Point Convert to Word Fixed Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 100100:
StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W));
/* DADD Doubleword Add
*/
000000 rs(5) rt(5) rd(5) 00000 101100:
uint64_t temp;
int carry;
temp = add_carry64(GPR[rs], GPR[rt], &carry);
if (carry) {
SignalException(IntegerOverflow);
} else {
GPR[rd] = temp;
}
/* DADDI Doubleword Add Immediate
*/
011000 rs(5) rt(5) immediate(16):
uint64_t temp;
int carry;
temp = add_carry64(GPR[rs], sign_extend(immediate, 16), &carry);
if (carry) {
SignalException(IntegerOverflow);
} else {
GPR[rt] = temp;
}
/* DADDIU Doubleword Add Immediate Unsigned
*/
011001 rs(5) rt(5) immediate(16):
GPR[rt] = GPR[rs] + sign_extend(immediate, 16);
/* DADDU Doubleword Add Unsigned
*/
000000 rs(5) rt(5) rd(5) 00000 101101:
GPR[rd] = GPR[rs] + GPR[rt];
/* DCLO/Z Count Leading Ones/Zeros in Doubleword
*/
011100 rs(5) rt(5) rd(5) 00000 10010 is_one(1):
int temp, i;
temp = 64;
for (i = 63; i >= 0; i--) {
if (bit(GPR[rs],i) == is_one) {
temp = 63 - i;
break;
}
}
GPR[rd] = temp;
/* DDIV Doubleword Divide
*/
000000 rs(5) rt(5) 00000 00000 011110:
LO = (int64_t)GPR[rs] / (int64_t)GPR[rt];
HI = (int64_t)GPR[rs] % (int64_t)GPR[rt];
/* DDIVU Doubleword Divide Unsigned
*/
000000 rs(5) rt(5) 00000 00000 011111:
LO = (uint64_t)GPR[rs] / (uint64_t)GPR[rt];
HI = (uint64_t)GPR[rs] % (uint64_t)GPR[rt];
/* DERET Debug Exception Return
*/
010000 1 0000 00000 00000 00000 011111:
Debug.DM=0;
Debug.IEXI=0;
PC = DEPC;
/* DIV Divide Word
*/
000000 rs(5) rt(5) 00000 00000 011010:
int64_t q,r;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
q = (int32_t)GPR[rs] / (int32_t)GPR[rt];
r = (int32_t)GPR[rs] % (int32_t)GPR[rt];
LO = sign_extend(q, 32);
HI = sign_extend(r, 32);
/* DIV.fmt Floating Point Divide
*/
010001 fmt(5) ft(5) fs(5) fd(5) 000011:
StoreFPR(fd, fmt, float_div(ValueFPR(fs, fmt),ValueFPR(ft, fmt)));
/* DIVU Divide Unsigned Word
*/
000000 rs(5) rt(5) 00000 00000 011011:
uint32_t q,r;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
q = (uint32_t)GPR[rs] / (uint32_t)GPR[rt];
r = (uint32_t)GPR[rs] % (uint32_t)GPR[rt];
LO = sign_extend(q, 32);
HI = sign_extend(r, 32);
/* DMFC0 Doubleword Move from Coprocessor 0
*/
010000 00001 rt(5) rd(5) 00000 000 sel(3):
SignalException(Unimplemented);
/* DMFC1 Doubleword Move from Floting Point
*/
010001 00001 rt(5) fs(5) 00000 000000:
GPR[rt] = ValueFPR(fs, UNINTERPRETED_DOUBLEWORD);
/* DMFC2 Doubleword Move from Coprocessor 2
*/
010010 00001 rt(5) Impl(16):
SignalException(Unimplemented);
/* DMTC0 Doubleword Move to Coprocessor 0
*/
010000 00101 rt(5) rd(5) 00000 000 sel(3):
SignalException(Unimplemented);
/* DMTC1 Doubleword Move to Floating Point
*/
010001 00101 rt(5) fs(5) 00000 000000:
StoreFPR(fs, UNINTERPRETED_DOUBLEWORD, GPR[rt]);
/* DMTC2 Doubleword Move to Coprocessor 2
*/
010010 00101 rt(5) Impl(16):
SignalException(Unimplemented);
/* DMULT Doubleword Multiply
*/
000000 rs(5) rt(5) 00000 00000 011100:
mult64(GPR[rs],GPR[rt],&LO,&HI);
/* DMULTU Doubleword Multiply Unsigned
*/
000000 rs(5) rt(5) 00000 00000 011101:
umult64(GPR[rs],GPR[rt],&LO,&HI);
/* DSLL Doubleword Shift Left Logical
*/
000000 00000 rt(5) rd(5) sa(5) 111000:
GPR[rd] = GPR[rt] << sa;
/* DSLL32 Doubleword Shift Left Logical Plus 32
*/
000000 00000 rt(5) rd(5) sa(5) 111100:
GPR[rd] = GPR[rt] << (32+sa);
/* DSLLV Doubleword Shift Left Logical Variable
*/
000000 rs(5) rt(5) rd(5) 00000 010100:
GPR[rd] = GPR[rt] << bits(GPR[rs],0,5);
/* DSRA Doubleword Shift Right Arithmetic
*/
000000 00000 rt(5) rd(5) sa(5) 111011:
GPR[rd] = ((int64_t)GPR[rt]) >> sa;
/* DSRA32 Doubleword Shift Right Arithmetic Plus 32
*/
000000 00000 rt(5) rd(5) sa(5) 111111:
sa += 32;
GPR[rd] = ((int64_t)GPR[rt]) >> sa;
/* DSRAV Doubleword Shift Right Arithmetic Variable
*/
000000 rs(5) rt(5) rd(5) 00000 010111:
int sa;
sa = bits(GPR[rs],0,5);
GPR[rd] = ((int64_t)GPR[rt]) >> sa;
/* DSLR Doubleword Shift Right Logical
*/
000000 00000 rt(5) rd(5) sa(5) 111010:
GPR[rd] = ((uint64_t)GPR[rt]) >> sa;
/* DSLR32 Doubleword Shift Right Logical Plus 32
*/
000000 00000 rt(5) rd(5) sa(5) 111110:
sa += 32;
GPR[rd] = ((uint64_t)GPR[rt]) >> sa;
/* DSRLV Doubleword Shift Right Logical Variable
*/
000000 rs(5) rt(5) rd(5) 00000 010110:
int sa;
sa = bits(GPR[rs],0,5);
GPR[rd] = ((uint64_t)GPR[rt]) >> sa;
/* DSUB Doubleword Subtract
*/
000000 rs(5) rt(5) rd(5) 00000 101110:
int carry;
int64_t temp;
temp = sub_carry64(GPR[rs],GPR[rt],&carry);
if (carry) {
SignalException(IntegerOverflow);
} else {
GPR[rd] = temp;
}
/* DSUBU Doubleword Subtract Unsigned
*/
000000 rs(5) rt(5) rd(5) 00000 101111:
GPR[rd] = GPR[rs] - GPR[rt];
/* ERET Exception Return
*/
010000 1 0000 00000 00000 00000 011000:
uint64_t temp;
if (Status.ERL == 1) {
temp = ErrorEPC;
Status.ERL = 0;
} else {
temp = EPC;
Status.EXL = 0;
}
PC = temp;
LLbit = 0;
/* FLOOR.L.fmt Floting Point Convert to Long Fixed Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 001011:
StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L));
/* FLOOR.W.fmt Floating Point Floor Convert to Word Fixed Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 001111:
StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W));
/* J Jump
*/
000010 instr_index(26):
/* I: */
NextInstruction();
/* I+1: */ PC = (PC & ((1 << 28)-1)) | (instr_index << 2);
/* JAL Jump and Link
*/
000011 instr_index(26):
/* I: */ GPR[31] = PC + 4;
NextInstruction();
/* I+1: */ PC = (PC & ((1 << 28)-1)) | (instr_index << 2);
/* JALR Jump and Link Register
*/
000000 rs(5) 00000 rd(5) hint(5) 001001:
uint64_t temp;
/* I: */ temp = GPR[rs];
GPR[rd] = PC + 4;
NextInstruction();
/* I+1: */ PC = temp;
/* JR Jump Register
*/
000000 rs(5) 00000 00000 hint(5) 001000:
uint64_t temp;
/* I: */ temp = GPR[rs];
NextInstruction();
/* I+1: */ PC=temp;
/* LB Load Byte
*/
100000 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
vAddr = GPR[base] + sign_extend(offset, 16);
doubleword = LoadMemory(vAddr, BYTE);
GPR[rt] = sign_extend(doubleword,8);
/* LBU Load Byte Unsigned
*/
100100 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
GPR[rt] = LoadMemory(vAddr, BYTE);
/* LD Load Doubleword
*/
110111 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,2) != 0) {
SignalException(AddressError);
}
GPR[rt] = LoadMemory(vAddr, DOUBLEWORD);
/* LDC1 Load Doubleword to Floating Point
*/
110101 base(5) ft(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,2) != 0) {
SignalException(AddressError);
}
StoreFPR(ft, UNINTERPRETED_DOUBLEWORD, LoadMemory(vAddr, DOUBLEWORD));
/* LDC2 Load Doubleword to Coprocessor 2
*/
110110 base(5) rt(5) offset(16):
SignalException(Unimplemented);
/* LDL Load Doubleword Left
*/
011010 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
int byte;
vAddr = GPR[base] + sign_extend(offset, 16);
byte = bits(vAddr,0,2);
doubleword = LoadMemory(vAddr, DOUBLEWORD);
GPR[rt] = (bits(doubleword,0,7+8*byte) << (64-8*byte)) | (bits(GPR[rt],0,63-8*byte));
/* LDR Load Doubleword Right
*/
011011 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
int byte;
vAddr = GPR[base] + sign_extend(offset, 16);
byte = bits(vAddr,0,2);
doubleword = LoadMemory(vAddr, DOUBLEWORD);
GPR[rt] = (bits(GPR[rt],64-8*byte,63) << (64-8*byte)) | bits(doubleword,8*byte,63);
/* LDXC1 Load Doubleword Indexed to Floating Point
*/
010011 base(5) index(5) 00000 fd(5) 000001:
uint64_t vAddr;
vAddr = GPR[base] + GPR[index];
if (bits(vAddr,0,2) != 0) {
SignalException(AddressError);
}
StoreFPR(fd, UNINTERPRETED_DOUBLEWORD, LoadMemory(vAddr, DOUBLEWORD));
/* LH Load Halfword
*/
100001 base(5) rt(5) offset(16):
uint64_t vAddr, doubleword;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bit(vAddr,0) != 0) {
SignalException(AddressError);
}
doubleword = LoadMemory(vAddr, HALFWORD);
GPR[rt] = sign_extend(doubleword,16);
/* LHU Load Halfword Unsigned
*/
100101 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bit(vAddr,0) != 0) {
SignalException(AddressError);
}
GPR[rt] = LoadMemory(vAddr, HALFWORD);
/* LL Load Linked Word
*/
110000 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
GPR[rt] = LoadMemory(vAddr, WORD);
LLbit = 1;
/* LLD Load Linked Doubleword
*/
110100 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,2) != 0) {
SignalException(AddressError);
}
GPR[rt] = LoadMemory(vAddr, DOUBLEWORD);
LLbit = 1;
/* LUI Load Upper Immediate
*/
001111 00000 rt(5) immediate(16):
GPR[rt] = sign_extend(immediate, 16) << 16;
/* LUXC1 Load Doubleword Indexed Unaligned to Floring Point
*/
010011 base(5) index(5) 00000 fd(5) 000101:
uint64_t vAddr;
vAddr = (GPR[base]+GPR[index]) & ~(7LL);
StoreFPR(fd, UNINTERPRETED_DOUBLEWORD, LoadMemory(vAddr, DOUBLEWORD));
/* LW Load Word
*/
100011 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
doubleword = LoadMemory(vAddr, WORD);
GPR[rt] = sign_extend(doubleword,32);
/* LWC1 Load Word to Floating Point
*/
110001 base(5) ft(5) offset(16):
uint64_t vAddr,doubleword;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
doubleword = LoadMemory(vAddr, WORD);
StoreFPR(ft, UNINTERPRETED_WORD, sign_extend(doubleword,32));
/* LWC2 Load Word to Coprocessor 2
*/
110010 base(5) rt(5) offset(16):
SignalException(Unimplemented);
/* LWL Load Word Left
*/
100010 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
int byte;
vAddr = GPR[base] + sign_extend(offset, 16);
byte = WORD - bits(vAddr,0,1);
doubleword = LoadMemory(vAddr, byte);
doubleword = (bits(doubleword,0,31-8*byte) << (8*byte)) | bits(GPR[rt],0,8*byte);
GPR[rt]=sign_extend(doubleword,32);
/* LWR Load Word Right
*/
100110 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
int byte,word;
vAddr = GPR[base] + sign_extend(offset, 16);
byte = bits(vAddr,0,1) + 1;
doubleword = LoadMemory(vAddr & ~3, byte);
doubleword = (bits(GPR[rt],8*byte,31) << (8*byte)) | bits(doubleword,0,8*byte);
if (byte == WORD)
sign_extend(doubleword,32);
GPR[rt]=doubleword;
/* LWU Load Word Unsigned
*/
100111 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset,16);
GPR[rt] = LoadMemory(vAddr, WORD);
/* LWXC1 Load Word Indexed to Floating Point
*/
010011 base(5) index(5) 00000 fd(5) 000000:
uint64_t vAddr,doubleword;
vAddr = GPR[base] + GPR[index];
doubleword = LoadMemory(vAddr, WORD);
StoreFPR(fd, UNINTERPRETED_DOUBLEWORD, sign_extend(doubleword, 32));
/* MADD Multiply and Add Word to Hi,Lo
*/
011100 rs(5) rt(5) 00000 00000 000000:
uint64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = (bits(HI,0,31) << 32) | bits(LO,0,31);
temp += mult32(bits(GPR[rs],0,31),bits(GPR[rt],0,31));
HI = sign_extend(bits(temp,32,63),32);
LO = sign_extend(bits(temp,0,31),32);
/* MADD.fmt Floating Point Multiply Add
*/
010011 fr(5) ft(5) fs(5) fd(5) 100 fmt(3):
uint64_t vfr,vfs,vft;
vfr = ValueFPR(fr, fmt);
vfs = ValueFPR(fs, fmt);
vft = ValueFPR(ft, fmt);
StoreFPR(fd, fmt, float_add(float_mult(vfs,vft),vfr));
/* MADDU Multiply and Add Unsigned Word to Hi,Lo
*/
011100 rs(5) rt(5) 00000 00000 000001:
uint64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = (bits(HI,0,31) << 32) | bits(LO,0,31);
temp += umult64(bits(GPR[rs],0,31),bits(GPR[rt],0,31),&LO,&HI);
HI = sign_extend(bits(temp,32,63), 32);
LO = sign_extend(bits(temp,0,31), 32);
/* MFC0 Move from Coprocessor 0
*/
010000 00000 rt(5) rd(5) 00000 000 sel(3):
SignalException(Unimplemented);
/* MFC1 Move from Coprocessor 1
*/
010001 00000 rt(5) fs(5) 00000 000000:
uint64_t data;
data = bits(ValueFPR(fs, UNINTERPRETED_WORD),0,31);
GPR[rt] = sign_extend(data, 32);
/* MFC2 Move from Coprocessor 2
*/
010010 00000 rt(5) Impl(16):
SignalException(Unimplemented);
/* MFHI Move from HI Register
*/
000000 00000 00000 rd(5) 00000 010000:
GPR[rd] = HI;
/* MFLO Move From LO Register
*/
000000 00000 00000 rd(5) 00000 010010:
GPR[rd] = LO;
/* MOV.fmt Floating Point Move
*/
010001 fmt(5) 00000 fs(5) fd(5) 000110:
StoreFPR(fd, fmt, ValueFPR(fs, fmt));
/* MOVF/T Move Conditional on Floating Point False/True
*/
000000 rs(5) cc(3) 0 tf(1) rd(5) 00000 000001:
if (FPConditionCode(cc) == tf) {
GPR[rd] = GPR[rs];
}
/* MOVF/T.fmt Floating Point Move Conditional on Floating Point False/True
*/
010001 fmt(5) cc(3) 0 tf(1) fs(5) fd(5) 010001:
SignalException(Unimplemented);
/*
if (fmt != PS) {
if (FPConditionCode(cc) == 1) {
StoreFPR(fd, fmt, ValueFPR(fs, fmt));
}
} else {
int mask=0;
if (FPConditionCode(cc+0) == 1) {
mask |= 0xF0;
}
if (FPConditionCode(cc+1) == 1) {
mask |= 0x0F;
}
StoreFPR(fd, PS, ByteMerge(mask, fd, fs));
} */
/* MOVN Move Conditional on Not Zero
*/
000000 rs(5) rt(5) rd(5) 00000 001011:
if (GPR[rt] != 0) {
GPR[rd] = GPR[rs];
}
/* MOVN.fmt Floating Point Move Conditional on Not Zero
*/
010001 fmt(5) rt(5) fs(5) fd(5) 010011:
if (GPR[rt] != 0) {
StoreFPR(fd, fmt, ValueFPR(fs, fmt));
}
/* MOVZ Move Conditional on Zero
*/
000000 rs(5) rt(5) rd(5) 00000 001010:
if (GPR[rt] == 0) {
GPR[rd] = GPR[rs];
}
/* MOVZ.fmt Floating Point Move Conditional on Zero
*/
010001 fmt(5) rt(5) fs(5) fd(5) 010010:
if (GPR[rt] == 0) {
StoreFPR(fd, fmt, ValueFPR(fs, fmt));
}
/* MSUB Multiply and Subtract Word to Hi,Lo
*/
011100 rs(5) rt(5) 00000 00000 000100:
int64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = (bits(HI,0,31)<<32) | bits(LO,0,31);
temp -= mult32(bits(GPR[rs],0,31),bits(GPR[rt],0,31));
HI = sign_extend(bits(temp,32,63),32);
LO = sign_extend(bits(temp,0,31),32);
/* MSUB.fmt Floating Point Multiply Subtract
*/
010011 fr(5) ft(5) fs(5) fd(5) 101 fmt(3):
float_t vfr,vft,vfs;
vfr = ValueFPR(fr, fmt);
vfs = ValueFPR(fs, fmt);
vft = ValueFPR(ft, fmt);
StoreFPR(fd, fmt, float_sub(float_mult(vfs,vft),vfr));
/* MSUBU Multiply and Subtract Word to Hi,Lo
*/
011100 rs(5) rt(5) 00000 00000 000101:
uint64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = (bits(HI,0,31)<<32) | bits(LO,0,31);
temp -= umult32(bits(GPR[rs],0,31),bits(GPR[rt],0,31));
HI = sign_extend(bits(temp,32,63),32);
LO = sign_extend(bits(temp,0,31),32);
/* MTC0 Move to Coprocessor 0
*/
010000 00100 rt(5) rd(5) 00000 000 sel(3):
SignalException(Unimplemented);
/* MTC1 Move Word to Floating Point
*/
010001 00100 rt(5) fs(5) 00000 000000:
StoreFPR(fs, UNINTERPRETED_WORD, bits(GPR[rt],0,31));
/* MTC2 Move Word to Coprocessor 2
*/
010010 00100 rt(5) Impl(16):
SignalException(Unimplemented);
/* MTHI Move to HI Register
*/
000000 rs(5) 00000 00000 00000 010001:
HI = GPR[rs];
/* MTLO Move to LO Register
*/
000000 rs(5) 00000 00000 00000 010011:
LO = GPR[rs];
/* MUL Multiply Word to GPR
*/
011100 rs(5) rt(5) rd(5) 00000 000010:
int32_t temp;
if (NotWordValue(GPR[rt]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = mult32(bits(GPR[rs],0,31), bits(GPR[rt],0,31));
GPR[rd] = sign_extend(temp,32);
/* MUL.fmt Floating Point Multiply
*/
010001 fmt(5) ft(5) fs(5) fd(5) 000010:
StoreFPR(fd, fmt, float_mult(ValueFPR(fs, fmt), ValueFPR(ft, fmt)));
/* MULT Multiply Word
*/
000000 rs(5) rt(5) 00000 00000 011000:
int64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = mult32(bits(GPR[rs],0,31), bits(GPR[rt],0,31));
LO = sign_extend(bits(temp,0,31),32);
HI = sign_extend(bits(temp,32,63),32);
/* MULTU Multiply Unsigned Word
*/
000000 rs(5) rt(5) 00000 00000 011001:
int64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = umult32(bits(GPR[rs],0,31), bits(GPR[rt],0,31));
LO = sign_extend(bits(temp,0,31),32);
HI = sign_extend(bits(temp,32,63),32);
/* NEG.fmt Floating Point Negate
*/
010001 fmt(5) 00000 fs(5) fd(5) 000111:
StoreFPR(fd, fmt, float_negate(ValueFPR(fs, fmt)));
/* NMADD.fmt Floating Point Negative Multiply Add
*/
010011 fr(5) ft(5) fs(5) fd(5) 110 fmt(3):
float_t vfr,vfs,vft;
vfr = ValueFPR(fr, fmt);
vfs = ValueFPR(fs, fmt);
vft = ValueFPR(ft, fmt);
StoreFPR(fd, fmt, float_negate(float_add(vfr,float_mult(vfs,vft))));
/* NMSUB.fmt Floating Point Negative Multiply Subtract
*/
010011 fr(5) ft(5) fs(5) fd(5) 111 fmt(3):
float_t vfr,vfs,vft;
vfr = ValueFPR(fr, fmt);
vfs = ValueFPR(fs, fmt);
vft = ValueFPR(ft, fmt);
StoreFPR(fd, fmt, float_negate(float_sub(float_mult(vfs,vft),vfr)));
/* NOP No operation
*/
000000 00000 00000 00000 00000 000000:
/* Do nothing */
/* NOR Not Or
*/
000000 rs(5) rt(5) rd(5) 00000 100111:
GPR[rd] = ~(GPR[rs] | GPR[rt]);
/* OR Or
*/
000000 rs(5) rt(5) rd(5) 00000 100101:
GPR[rd] = GPR[rs] | GPR[rt];
/* ORI Or Immediate
*/
001101 rs(5) rt(5) immediate(16):
GPR[rt] = GPR[rs] | zero_extend(immediate,16);
/* PLL.PS Pair Lower Lower
*/
010001 10110 ft(5) fs(5) fd(5) 101100:
StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),0,31) << 32) | bits(ValueFPR(ft, PS),0,31));
/* PLU.PS Pair Lower Upper
*/
010001 10110 ft(5) fs(5) fd(5) 101101:
StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),0,31) << 32) | bits(ValueFPR(ft, PS),32,63));
/* PREF Prefetch
*/
110011 base(5) hint(5) offset(16):
/* Do nothing */
/* PREFI Prefetch Indexed
*/
010011 base(5) index(5) hint(5) 00000 001111:
/* Do nothing */
/* PUL.PS Pair Upper Lower
*/
010001 10110 ft(5) fs(5) fd(5) 101110:
StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),32,63) << 32) | bits(ValueFPR(ft, PS),0,31));
/* PUU.PS Pair Upper Upper
*/
010001 10110 ft(5) fs(5) fd(5) 101111:
StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),32,63) << 32) | bits(ValueFPR(ft, PS),32,63));
/* RECIP.fmt Reciprocal Approximation
*/
010001 fmt(5) 00000 fs(5) fd(5) 010101:
StoreFPR(fd, fmt, float_recip(ValueFPR(fs, fmt)));
/* ROUND.L.fmt Floating point Round
*/
010001 fmt(5) 00000 fs(5) fd(5) 001000:
StoreFPR(fd, L, ConvertFmt(ValueFPR(fd, fmt), fmt, L));
/* ROUND.W.fmt Floating point Round
*/
010001 fmt(5) 00000 fs(5) fd(5) 001100:
StoreFPR(fd, W, ConvertFmt(ValueFPR(fd, fmt), fmt, W));
/* RSQRT.fmt Reciprocal Square Root Approximation
*/
010001 fmt(5) 00000 fs(5) fd(5) 010110:
StoreFPR(fd, fmt, float_recip(float_sqr(ValueFPR(fs, fmt))));
/* SB Store Byte
*/
101000 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset,16);
StoreMemory(vAddr, BYTE, GPR[rt]);
/* SC Store Conditional Word
*/
111000 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset,16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
if (LLbit) {
StoreMemory(vAddr, BYTE, GPR[rt]);
}
GPR[rt] = LLbit;
/* SCD Store Conditional Doubleword
*/
111100 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset,16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
if (LLbit) {
StoreMemory(vAddr, DOUBLEWORD, GPR[rt]);
}
GPR[rt] = LLbit;
/* SD Store Doubleword
*/
111111 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
vAddr = GPR[base] + sign_extend(offset,16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
doubleword = GPR[rt];
StoreMemory(vAddr, DOUBLEWORD, doubleword);
/* SDBBP Software Debug Breakpoint
*/
011100 code(20) 111111:
if (Debug.DM == 0) {
SignalDebugBreakpointException();
} else {
SignalDebugModeBreakpointException();
}
/* SDC1 Store Doubleword from Floating Point
*/
111101 base(5) ft(5) offset(16):
uint64_t vAddr,doubleword;
vAddr = GPR[base] + sign_extend(offset,16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
doubleword = ValueFPR(ft, UNINTERPRETED_DOUBLEWORD);
StoreMemory(vAddr, DOUBLEWORD, doubleword);
/* SDC2 Store Doubleword from Coprocessor 2
*/
111110 base(5) rt(5) offset(16):
SignalException(Unimplemented);
/* SDL Store Doubleword Left
*/
101100 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
int byte;
vAddr = GPR[base] + sign_extend(offset,16);
byte = bits(vAddr,0,2);
doubleword = bits(GPR[rt],56-8*byte,63);
StoreMemory(vAddr, DOUBLEWORD, doubleword);
/* SDR Store Doubleword Right
*/
101101 base(5) rt(5) offset(16):
uint64_t vAddr,doubleword;
int byte;
vAddr = GPR[base] + sign_extend(offset,16);
byte = bits(vAddr,0,2);
doubleword = bits(GPR[rt],8*byte,63) << (8*byte);
StoreMemory(vAddr, DOUBLEWORD, doubleword);
/* SDXC1 Store Doubleword Indexed from Floating Point
*/
010011 base(5) index(5) fs(5) 00000 001001:
uint64_t vAddr,doubleword;
vAddr = GPR[base] + GPR[index];
if (bits(vAddr,0,2) != 0) {
SignalException(AddressError);
}
doubleword = ValueFPR(fs, UNINTERPRETED_DOUBLEWORD);
StoreMemory(vAddr, DOUBLEWORD, doubleword);
/* SH Store Halfword
*/
101001 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset,16);
if (bit(vAddr,0) != 0) {
SignalException(AddressError);
}
StoreMemory(vAddr, HALFWORD, GPR[rt]);
/* SLL Shift Word Left Logical
*/
000000 00000 rt(5) rd(5) sa(5) 000000:
GPR[rd] = sign_extend(GPR[rt] << sa,32);
/* SLLV Shift Word Left Logical Variable
*/
000000 rs(5) rt(5) rd(5) 00000 000100:
GPR[rd] = sign_extend(GPR[rt] << bits(GPR[rs],0,4),32);
/* SLT Set on Less Than
*/
000000 rs(5) rt(5) rd(5) 00000 101010:
if ((int64_t)GPR[rs] < (int64_t)GPR[rt]) {
GPR[rd] = 1;
} else {
GPR[rd] = 0;
}
/* SLTI Set on Less Than Immediate
*/
001010 rs(5) rt(5) immediate(16):
if ((int64_t)GPR[rs] < (int64_t)sign_extend(immediate, 16) ) {
GPR[rt] = 1;
} else {
GPR[rt] = 0;
}
/* SLTIU Set on Less Than Immediate Unsigned
*/
001011 rs(5) rt(5) immediate(16):
if (GPR[rs] < sign_extend(immediate,16)) {
GPR[rt] = 1;
} else {
GPR[rt] = 0;
}
/* SLTU Set on Less than Unsigned
*/
000000 rs(5) rt(5) rd(5) 00000 101011:
if (GPR[rs] < GPR[rt]) {
GPR[rd] = 1;
} else {
GPR[rd] = 0;
}
/* SQRT.fmt Floating Point Square Root
*/
010001 fmt(5) 00000 fs(5) fd(5) 000100:
StoreFPR(fd, fmt, float_sqr(ValueFPR(fs, fmt)));
/* SRA Shift Word Right Arithmetic
*/
000000 00000 rt(5) rd(5) sa(5) 000011:
uint64_t temp;
if (NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
GPR[rd] = sign_extend(GPR[rt] >> sa,32-sa);
/* SRAV Shift Word Right Arithmetic Variable
*/
000000 rs(5) rt(5) rd(5) 00000 000111:
int sa;
uint64_t temp;
if (NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
sa = bits(GPR[rs],0,4);
GPR[rd] = sign_extend(GPR[rt] >> sa,32-sa);
/* SRL Shift Word Right Logical
*/
000000 00000 rt(5) rd(5) sa(5) 000010:
if (NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
GPR[rd] = zero_extend(GPR[rt] >> sa,32-sa);
/* SRLV Shift Word Right Logical Variable
*/
000000 rs(5) rt(5) rd(5) 00000 000110:
int sa;
if (NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
sa = bits(GPR[rs],0,4);
GPR[rd] = zero_extend(GPR[rt] >> sa,32-sa);
/* SUB Subtract Word
*/
000000 rs(5) rt(5) rd(5) 00000 100010:
uint64_t temp;
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
temp = (bit(GPR[rs],31) << 32) | bits(GPR[rs],0,31);
temp -= (bit(GPR[rt],31) << 32) | bits(GPR[rt],0,31);
if (bit(temp,32) != bit(temp,31)) {
SignalException(IntegerOverflow);
} else {
GPR[rd] = sign_extend(temp,32);
}
/* SUB.fmt Floating Point Subtract
*/
010001 fmt(5) ft(5) fs(5) fd(5) 000001:
StoreFPR(fd, fmt, float_sub(ValueFPR(fs, fmt), ValueFPR(ft, fmt)));
/* SUBU Subtract Unsigned Word
*/
000000 rs(5) rt(5) rd(5) 00000 100011:
if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) {
UNPREDICTABLE;
}
GPR[rd] = sign_extend((int32_t)GPR[rs] - (int32_t)GPR[rt], 32);
/* SUXC1 Store Doubleword Indexed Unaligned from Floating Point
*/
010011 base(5) index(5) fs(5) 00000 001101:
uint64_t vAddr, doubleword;
vAddr = bits(GPR[base] + GPR[index],3,63) << 3;
doubleword = ValueFPR(fs, UNINTERPRETED_DOUBLEWORD);
StoreMemory(vAddr, DOUBLEWORD, doubleword);
/* SW Store Word
*/
101011 base(5) rt(5) offset(16):
uint64_t vAddr;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
StoreMemory(vAddr, WORD, GPR[rt]);
/* SWC1 Store Word from Floating Point
*/
111001 base(5) ft(5) offset(16):
uint64_t vAddr, doubleword;
vAddr = GPR[base] + sign_extend(offset, 16);
if (bits(vAddr,0,1) != 0) {
SignalException(AddressError);
}
doubleword = ValueFPR(ft, UNINTERPRETED_WORD);
StoreMemory(vAddr, WORD, doubleword);
/* SWC2 Store Word from Coprocessor 2
*/
111010 base(5) rt(5) offset(16):
SignalException(Unimplemented);
/* SWL Store Word Left
*/
101010 base(5) rt(5) offset(16):
uint64_t vAddr;
int byte;
vAddr = GPR[base] + sign_extend(offset, 16);
byte = WORD - bits(vAddr,0,1);
StoreMemory(vAddr, byte, GPR[rt] >> (8*(WORD-byte)));
/* SWR Store Word Right
*/
101110 base(5) rt(5) offset(16):
uint64_t vAddr;
int byte;
vAddr = GPR[base] + sign_extend(offset, 16);
byte = bits(vAddr,0,1) + 1;
StoreMemory(vAddr & ~3, byte, GPR[rt] >> (8*(WORD-byte)));
/* SWXC1 Store Word Indexed from Floating Point
*/
010011 base(5) index(5) fs(5) 00000 001000:
uint64_t vAddr, doubleword;
vAddr = GPR[base] + GPR[index];
if (bits(vAddr,0,2) != 0) {
SignalException(AddressError);
}
doubleword = ValueFPR(fs, UNINTERPRETED_WORD);
StoreMemory(vAddr, WORD, doubleword);
/* SYNC Synchonize Shared Memory
*/
000000 00000 00000 00000 stype(5) 001111:
/* SyncOperation(stype); */
/* SYSCALL System Call
*/
000000 code(20) 001100:
SignalException(SystemCall);
/* TEQ Trap if Equal
*/
000000 rs(5) rt(5) code(10) 110100:
if (GPR[rs] == GPR[rt]) {
SignalException(Trap);
}
/* TEQI Trap if Equal Immediate
*/
000001 rs(5) 01100 immediate(16):
if (GPR[rs] == sign_extend(immediate, 16)) {
SignalException(Trap);
}
/* TGE Trap if Greater or Equal
*/
000000 rs(5) rt(5) code(10) 110000:
if ((int64_t)GPR[rs] >= (int64_t)GPR[rt]) {
SignalException(Trap);
}
/* TGEI Trap if Greater or Equal Immediate
*/
000001 rs(5) 01000 immediate(16):
if ((int64_t)GPR[rs] >= (int64_t)sign_extend(immediate, 16)) {
SignalException(Trap);
}
/* TGEIU Trap if Greator or Equal Immediate Unsigned
*/
000001 rs(5) 01001 immediate(16):
if (GPR[rs] >= sign_extend(immediate, 16)) {
SignalException(Trap);
}
/* TGEU Trap if Greater or Equal Unsigned
*/
000000 rs(5) rt(5) code(10) 110001:
if (GPR[rs] >= GPR[rt]) {
SignalException(Trap);
}
/* TLBP Probe TLB for Matching Entry
*/
010000 1 0000 00000 00000 00000 001000:
SignalException(Unimplemented);
/* TLBR Read Indexed TLB Entry
*/
010000 1 0000 00000 00000 00000 000001:
SignalException(Unimplemented);
/* TLBWI Write Indexed TLB Entry
*/
010000 1 0000 00000 00000 00000 000010:
SignalException(Unimplemented);
/* TLBWR Write Random TLB Entry
*/
010000 1 0000 00000 00000 00000 000110:
SignalException(Unimplemented);
/* TLT Trap if Less Than
*/
000000 rs(5) rt(5) code(10) 110010:
if ((int64_t)GPR[rs] < (int64_t)GPR[rt]) {
SignalException(Trap);
}
/* TLTI Trap if Less Than Immediate
*/
000001 rs(5) 01010 immediate(16):
if ((int64_t)GPR[rs] < (int64_t)sign_extend(immediate, 16)) {
SignalException(Trap);
}
/* TLTIO Trap if Less Than Immediate Unsigned
*/
000001 rs(5) 01011 immediate(16):
if (GPR[rs] < sign_extend(immediate, 16)) {
SignalException(Trap);
}
/* TLTU Trap if Less Than Unsigned
*/
000000 rs(5) rt(5) code(10) 110011:
if (GPR[rs] < GPR[rt]) {
SignalException(Trap);
}
/* TNE Trap if Not Equal
*/
000000 rs(5) rt(5) code(10) 110110:
if (GPR[rs] != GPR[rt]) {
SignalException(Trap);
}
/* TNEI Trap if Not Equal Immediate
*/
000001 rs(5) 01110 immediate(16):
if (GPR[rs] != sign_extend(immediate, 16)) {
SignalException(Trap);
}
/* TRUNC.L.fmt Floating Point Truncate to Long Fixed Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 001001:
StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L));
/* TRUNC.W.fmt Floating Point truncate to Word Fixed Point
*/
010001 fmt(5) 00000 fs(5) fd(5) 001101:
StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W));
/* WAIT Enter Standby Mode
*/
010000 1 code(19) 100000:
WaitForInterrupt(code);
/* XOR Exclusive Or
*/
000000 rs(5) rt(5) rd(5) 00000 100110:
GPR[rd] = GPR[rs] ^ GPR[rt];
/* XORI Exclusive Or Immediate
*/
001110 rs(5) rt(5) immediate(16):
GPR[rt] = GPR[rs] ^ zero_extend(immediate, 16);
/* ADD.fmt Add Float
* This is at the end, because otherwise we miss some of the
* "pull crud from FPU special registers" instructions.
*/
010001 fmt(5) ft(5) fs(5) fd(5) 000000:
StoreFPR(fd, fmt, float_add(ValueFPR(fs, fmt),ValueFPR(ft, fmt)));
[-- Attachment #1.3: spec2c.pl --]
[-- Type: application/x-perl, Size: 2882 bytes --]
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] New emulator: MIPS-user
2005-02-09 18:49 [Qemu-devel] New emulator: MIPS-user McMullan, Jason
@ 2005-02-09 22:02 ` J. Mayer
2005-02-10 5:35 ` Ming-Ching Tiew
2005-02-10 13:28 ` McMullan, Jason
0 siblings, 2 replies; 6+ messages in thread
From: J. Mayer @ 2005-02-09 22:02 UTC (permalink / raw)
To: qemu-devel
On Wed, 2005-02-09 at 19:48, McMullan, Jason wrote:
> So, I'm working on converting my pure-emulation mips-user emulator
> ( http://www.sourceforge.net/projects/gehail ) to QEMU's dynamic
> code generator system, and I was wondering if there's a document
> that describes the general architecture, and:
>
I wrote a MIPS32 emulation for qemu (which is still not released because
of lack of time for debugging). It supports MIPS32 with MIPS r4k<x> MMU
and preliminary code for MIPS16. There is some preliminary support for
MIPS64 (just load and stores, for now).
I did load a linux kernel until the "unable to find init" panic message
using this code.
Would you like to see it to avoid duplicate effort ?
Note that I did a system emulation, with no user mode only support.
--
J. Mayer <l_indien@magic.fr>
Never organized
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] New emulator: MIPS-user
2005-02-09 22:02 ` J. Mayer
@ 2005-02-10 5:35 ` Ming-Ching Tiew
2005-02-10 13:28 ` McMullan, Jason
1 sibling, 0 replies; 6+ messages in thread
From: Ming-Ching Tiew @ 2005-02-10 5:35 UTC (permalink / raw)
To: qemu-devel
From: "J. Mayer" <l_indien@magic.fr>
To: <qemu-devel@nongnu.org>
Sent: Thursday, February 10, 2005 6:02 AM
Subject: Re: [Qemu-devel] New emulator: MIPS-user
>
> I wrote a MIPS32 emulation for qemu (which is still not released because
> of lack of time for debugging). It supports MIPS32 with MIPS r4k<x> MMU
> and preliminary code for MIPS16. There is some preliminary support for
> MIPS64 (just load and stores, for now).
> I did load a linux kernel until the "unable to find init" panic message
> using this code.
> Would you like to see it to avoid duplicate effort ?
> Note that I did a system emulation, with no user mode only support.
> --
It will be good if it could emulate WRT54g or the related hardware used
by the those Linux-based firewall/router. Those hardware are based on MIPSEL.
Cheers
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] New emulator: MIPS-user
2005-02-09 22:02 ` J. Mayer
2005-02-10 5:35 ` Ming-Ching Tiew
@ 2005-02-10 13:28 ` McMullan, Jason
2005-02-11 14:17 ` J. Mayer
1 sibling, 1 reply; 6+ messages in thread
From: McMullan, Jason @ 2005-02-10 13:28 UTC (permalink / raw)
To: J. Mayer; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 791 bytes --]
On Wed, 2005-02-09 at 23:02 +0100, J. Mayer wrote:
> I wrote a MIPS32 emulation for qemu (which is still not released because
> of lack of time for debugging). It supports MIPS32 with MIPS r4k<x> MMU
> and preliminary code for MIPS16. There is some preliminary support for
> MIPS64 (just load and stores, for now).
> I did load a linux kernel until the "unable to find init" panic message
> using this code.
> Would you like to see it to avoid duplicate effort ?
> Note that I did a system emulation, with no user mode only support.
That would be fantastic! I've already done the user-mode support code,
and I could flesh out the MIPS64 and FPU support.
Can you email me your code, or give me a URL?
--
Jason McMullan <jason.mcmullan@timesys.com>
TimeSys Corporation
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] New emulator: MIPS-user
2005-02-10 13:28 ` McMullan, Jason
@ 2005-02-11 14:17 ` J. Mayer
[not found] ` <1108135188.15068.5.camel@localhost.localdomain>
0 siblings, 1 reply; 6+ messages in thread
From: J. Mayer @ 2005-02-11 14:17 UTC (permalink / raw)
To: McMullan, Jason; +Cc: qemu-devel
On Thu, 2005-02-10 at 14:26, McMullan, Jason wrote:
> On Wed, 2005-02-09 at 23:02 +0100, J. Mayer wrote:
> > I wrote a MIPS32 emulation for qemu (which is still not released because
> > of lack of time for debugging). It supports MIPS32 with MIPS r4k<x> MMU
> > and preliminary code for MIPS16. There is some preliminary support for
> > MIPS64 (just load and stores, for now).
> > I did load a linux kernel until the "unable to find init" panic message
> > using this code.
> > Would you like to see it to avoid duplicate effort ?
> > Note that I did a system emulation, with no user mode only support.
>
> That would be fantastic! I've already done the user-mode support code,
> and I could flesh out the MIPS64 and FPU support.
>
> Can you email me your code, or give me a URL?
As I was reworking some parts of this code, my current version may be
quite broken.
So, I'll take a close look this week-end and send you a snapshot.
Regards.
--
J. Mayer <l_indien@magic.fr>
Never organized
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-02-13 15:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-09 18:49 [Qemu-devel] New emulator: MIPS-user McMullan, Jason
2005-02-09 22:02 ` J. Mayer
2005-02-10 5:35 ` Ming-Ching Tiew
2005-02-10 13:28 ` McMullan, Jason
2005-02-11 14:17 ` J. Mayer
[not found] ` <1108135188.15068.5.camel@localhost.localdomain>
2005-02-13 15:43 ` J. Mayer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).