All of lore.kernel.org
 help / color / mirror / Atom feed
From: "McMullan, Jason" <jason.mcmullan@timesys.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] New emulator: MIPS-user
Date: Wed, 09 Feb 2005 13:49:49 -0500
Date: Wed, 9 Feb 2005 13:48:18 -0500	[thread overview]
Message-ID: <1107974989.17910.6.camel@jmcmullan> (raw)


[-- 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 --]

             reply	other threads:[~2005-02-09 19:13 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-09 18:49 McMullan, Jason [this message]
2005-02-09 22:02 ` [Qemu-devel] New emulator: MIPS-user 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1107974989.17910.6.camel@jmcmullan \
    --to=jason.mcmullan@timesys.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.