1754 lines
57 KiB
Plaintext
1754 lines
57 KiB
Plaintext
############################
|
|
#
|
|
# MIPS32
|
|
# Basic and FP (COP1) instructions
|
|
#
|
|
# (See bottom of file for MIPS64 instructions included with MIPS32)
|
|
#
|
|
############################
|
|
|
|
@if defined(ISA_VARIANT)
|
|
@define AMODE "ISA_MODE=0" # ISA_MODE must restrict MIPS instruction decoding and require ISA_MODE=0
|
|
@else
|
|
@define AMODE "epsilon" # Mips16 instructions not supported - Mips32 only
|
|
@endif
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0010 0000
|
|
:add RD32, RS32src, RT32src is $(AMODE) & prime=0 & sa=0 & fct=0x20 & RD32 & RS32src & RT32src & RD {
|
|
RD32 = RS32src + RT32src;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
|
|
# 0010 01ss ssst tttt iiii iiii iiii iiii
|
|
:addiu RT32, RS32src, simmed is $(AMODE) & prime=9 & RT32 & RS32src & simmed & RT {
|
|
RT32 = RS32src + simmed;
|
|
@ifdef MIPS64
|
|
RT = sext(RT32);
|
|
@endif
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0010 0001
|
|
:addu RD32, RS32src, RT32src is $(AMODE) & prime=0 & fct=0x21 & RS32src & RT32src & RD32 & sa=0 & RD {
|
|
RD32 = RS32src + RT32src;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0010 0100
|
|
:and RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x24 & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = RSsrc & RTsrc;
|
|
}
|
|
|
|
# 0011 00ss ssst tttt iiii iiii iiii iiii
|
|
:andi RT, RSsrc, immed is $(AMODE) & prime=0xC & RSsrc & RT & immed {
|
|
RT = RSsrc & immed;
|
|
}
|
|
|
|
# 0001 0000 0000 0000 iiii iiii iiii iiii
|
|
:b Rel16 is $(AMODE) & prime=4 & rs=0 & rt=0 & Rel16 {
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
|
|
# 0001 00ss ssst tttt iiii iiii iiii iiii
|
|
:beq RSsrc, RTsrc, Rel16 is $(AMODE) & prime=4 & RSsrc & RTsrc & Rel16 {
|
|
delayflag:1 = ( RSsrc == RTsrc );
|
|
delayslot( 1 );
|
|
if delayflag goto Rel16;
|
|
}
|
|
|
|
# 0000 01ss sss0 0001 iiii iiii iiii iiii
|
|
:bgez RSsrc, Rel16 is $(AMODE) & prime=1 & cond=1 & RSsrc & Rel16 {
|
|
delayflag:1 = ( RSsrc s>= 0 );
|
|
delayslot( 1 );
|
|
if delayflag goto Rel16;
|
|
}
|
|
# 0001 11ss sss0 0000 iiii iiii iiii iiii
|
|
:bgtz RSsrc, Rel16 is $(AMODE) & prime=7 & cond=0 & RSsrc & Rel16 {
|
|
delayflag:1 = ( RSsrc s> 0 );
|
|
delayslot( 1 );
|
|
if delayflag goto Rel16;
|
|
}
|
|
# 0001 10ss sss0 0000 iiii iiii iiii iiii
|
|
:blez RSsrc, Rel16 is $(AMODE) & prime=6 & cond=0 & RSsrc & Rel16 {
|
|
delayflag:1 = ( RSsrc s<= 0 );
|
|
delayslot( 1 );
|
|
if delayflag goto Rel16;
|
|
}
|
|
|
|
# 0000 01ss sss0 0000 iiii iiii iiii iiii
|
|
:bltz RSsrc, Rel16 is $(AMODE) & prime=1 & cond=0 & RSsrc & Rel16 {
|
|
delayflag:1 = ( RSsrc s< 0 );
|
|
delayslot( 1 );
|
|
if delayflag goto Rel16;
|
|
}
|
|
# 0001 01ss ssst tttt iiii iiii iiii iiii
|
|
:bne RSsrc, RTsrc, Rel16 is $(AMODE) & prime=5 & RSsrc & RTsrc & Rel16 {
|
|
delayflag:1 = ( RSsrc != RTsrc );
|
|
delayslot( 1 );
|
|
if delayflag goto Rel16;
|
|
}
|
|
|
|
# 0000 00cc cccc cccc cccc cccc cc00 1101
|
|
:break breakcode is $(AMODE) & prime=0 & fct=0xD & breakcode {
|
|
tmp:4=breakcode;
|
|
trap(tmp);
|
|
}
|
|
|
|
# 1011 11bb bbbo oooo iiii iiii iiii iiii
|
|
:cache op, OFF_BASER6 is $(AMODE) & ((prime=0x2F & REL6=0) | (prime=0x1F & REL6=1 & fct=0x25 & bit6=0)) & OFF_BASER6 & op {
|
|
cacheOp(op:1, OFF_BASER6);
|
|
}
|
|
|
|
:cachee op, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x1B & bit6=0 & OFF_BASER6 & op {
|
|
cacheOp(op:1, OFF_BASER6);
|
|
}
|
|
|
|
:cfc0 RT, RD0 is $(AMODE) & prime=0x10 & copop=2 & RT & RD0 & bigfunct=0 {
|
|
RT = sext( RD0:$(SIZETO4) );
|
|
}
|
|
|
|
# 0100 1000 010t tttt ssss s000 0000 0000
|
|
:cfc2 RT, immed is $(AMODE) & prime=0x12 & copop=2 & RT & immed {
|
|
tmp:4 = getCopControlWord( 2:1, immed:4 );
|
|
RT = sext(tmp);
|
|
}
|
|
|
|
# Special case of ADDU
|
|
# 0000 0000 0000 0000 dddd d000 0010 0001
|
|
:clear RD is $(AMODE) & prime=0 & fct=0x21 & rs=0 & rt=0 & RD & sa=0 {
|
|
RD = 0;
|
|
}
|
|
|
|
define pcodeop special2;
|
|
|
|
# 0111 00ss ssst tttt dddd daaa aaxx xyyy
|
|
# valid values of x and y:
|
|
# x: 0 y: 3,6,7
|
|
# x: 1 y: 0-7
|
|
# x: 2 y: 0-7
|
|
# x: 3 y: 0-7
|
|
# x: 4 y: 2,3,6,7
|
|
# x: 5 y: 0-7
|
|
# x: 6 y: 0-7
|
|
# x: 7 y: 0-6
|
|
:SPECIAL2 RD, RSsrc, RTsrc, sa, fct is $(AMODE) & prime=0x1C & sa & RD & RSsrc & RTsrc & fct {
|
|
tmp:1 = fct;
|
|
tmp2:1 = sa;
|
|
RD = special2(RSsrc, RTsrc, tmp2, tmp);
|
|
}
|
|
|
|
# 0100 101c cccc cccc cccc cccc cccc cccc
|
|
:cop2 cofun is $(AMODE) & prime=0x12 & bit25=1 & cofun {
|
|
arg:4 = cofun;
|
|
copFunction(2:1, arg);
|
|
}
|
|
|
|
:ctc0 RTsrc, RD0 is $(AMODE) & prime=0x10 & copop=6 & RTsrc & RD0 & bigfunct=0 {
|
|
RD0 = RTsrc;
|
|
}
|
|
# 0100 1000 110t tttt iiii iiii iiii iiii
|
|
:ctc2 RTsrc, immed is $(AMODE) & prime=0x12 & copop=6 & RTsrc & immed {
|
|
setCopControlWord( 2:1, immed:4, RTsrc );
|
|
}
|
|
|
|
# 0100 0010 0000 0000 0000 0000 0001 1111
|
|
:deret is $(AMODE) & prime=0x10 & bit25=1 & copfill=0x0 & fct=0x1F {
|
|
return[DEPC];
|
|
}
|
|
|
|
# 0100 0001 011t tttt 0110 0000 0000 0000
|
|
:di is $(AMODE) & prime=0x10 & mfmc0=0x0B & rd=0x0C & fct2=0x0 & bit5=0x0 & zero3=0x0 & rt=0x0 {
|
|
zero = Status;
|
|
Status = Status & -2; # clearing last bit (ffff..fffe == -2 signed)
|
|
}
|
|
:di RT is $(AMODE) & prime=0x10 & mfmc0=0x0B & rd=0x0C & fct2=0x0 & bit5=0x0 & zero3=0x0 & RT {
|
|
RT = Status;
|
|
Status = Status & -2; # clearing last bit (ffff..fffe == -2 signed)
|
|
}
|
|
|
|
# 0000 0000 0000 0000 0000 0000 1100 0000
|
|
:ehb is $(AMODE) & prime=0x0 & rs=0x0 & rt=0x0 & rd=0x0 & fct2=0x3 & fct=0x0 {
|
|
}
|
|
|
|
# 0100 0001 011t tttt 0110 0000 0010 0000
|
|
:ei is $(AMODE) & prime=0x10 & mfmc0=0x0B & rd=0x0C & fct2=0x0 & bit5=0x01 & zero3=0x0 & rt=0x0 {
|
|
zero = Status;
|
|
Status = Status | 1;
|
|
}
|
|
:ei RT is $(AMODE) & prime=0x10 & mfmc0=0x0B & rd=0x0C & fct2=0x0 & bit5=0x01 & zero3=0x0 & RT {
|
|
RT = Status;
|
|
Status = Status | 1;
|
|
}
|
|
|
|
# 0100 0010 0000 0000 0000 0000 0001 1000
|
|
:eret is $(AMODE) & prime=0x10 & fct=0x18 & bit25=1 & copfill=0 {
|
|
return[EPC];
|
|
}
|
|
|
|
:eretnc is $(AMODE) & prime=0x10 & fct=0x18 & bit25=1 & copfill=1 {
|
|
return[EPC];
|
|
}
|
|
|
|
# 0111 11ss ssst tttt mmmm mLLL LL00 0000
|
|
:ext RT, RSsrc, lsb, ExtSize is $(AMODE) & prime=0x1F & fct=0x0 & RT & RSsrc & lsb & msbd & ExtSize {
|
|
# Extract Bit Field
|
|
# RT = extractField(RSsrc, msbd:1, lsb:1);
|
|
# Note that msbd = size - 1
|
|
@if REGSIZE == "4"
|
|
rs_tmp:4 = RSsrc << (32 - (msbd + lsb + 1));
|
|
rs_tmp = rs_tmp >> (32 - (msbd + 1));
|
|
RT = zext(rs_tmp);
|
|
@else
|
|
rs_tmp:8 = RSsrc << (64 - (msbd + lsb + 1));
|
|
rs_tmp = rs_tmp >> (64 - (msbd + 1));
|
|
RT = zext(rs_tmp);
|
|
@endif
|
|
}
|
|
|
|
# 0111 11ss ssst tttt mmmm mLLL LL00 0100
|
|
:ins RT, RSsrc, lsb, InsSize is $(AMODE) & prime=0x1F & fct=0x04 & RT & RTsrc & RSsrc & lsb & msbd & InsSize {
|
|
tmpa:$(REGSIZE) = -1;
|
|
tmpa = tmpa >> ($(REGSIZE) - InsSize);
|
|
tmpb:$(REGSIZE) = RSsrc & tmpa;
|
|
tmpa = tmpa << lsb;
|
|
tmpa = ~tmpa;
|
|
tmpb = tmpb << lsb;
|
|
RT = (RT & tmpa) | tmpb;
|
|
}
|
|
|
|
# 0000 10aa aaaa aaaa aaaa aaaa aaaa aaaa
|
|
:j Abs26 is $(AMODE) & prime=2 & Abs26 {
|
|
delayslot( 1 );
|
|
goto Abs26;
|
|
}
|
|
# 0000 11aa aaaa aaaa aaaa aaaa aaaa aaaa
|
|
:jal Abs26 is $(AMODE) & prime=3 & Abs26 {
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
call Abs26;
|
|
}
|
|
@ifdef ISA_VARIANT
|
|
# 0000 00ss sss0 0000 dddd dhhh hh00 1001
|
|
:jalr RD, RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & RD {
|
|
build RD;
|
|
build RSsrc;
|
|
JXWritePC(RSsrc);
|
|
RD = inst_next;
|
|
delayslot( 1 );
|
|
call [pc];
|
|
}
|
|
:jalr RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & rd=0x1F {
|
|
build RSsrc;
|
|
JXWritePC(RSsrc);
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
call [pc];
|
|
}
|
|
@else
|
|
# 0000 00ss sss0 0000 dddd dhhh hh00 1001
|
|
:jalr RD, RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & RD {
|
|
RD = inst_next;
|
|
delayslot( 1 );
|
|
tmp:$(ADDRSIZE) = 0;
|
|
ValCast(tmp,RSsrc);
|
|
call [tmp];
|
|
}
|
|
:jalr RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & rd=0x1F {
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
tmp:$(ADDRSIZE) = 0;
|
|
ValCast(tmp,RSsrc);
|
|
call [tmp];
|
|
}
|
|
@endif
|
|
@ifdef ISA_VARIANT
|
|
# 0000 00ss sss0 0000 dddd d1hh hh00 1001
|
|
:jalr.hb RD, RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & RD & bit10=1 {
|
|
build RD;
|
|
build RSsrc;
|
|
JXWritePC(RSsrc);
|
|
RD = inst_next;
|
|
delayslot( 1 );
|
|
call [pc];
|
|
}
|
|
:jalr.hb RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & rd=0x1F & bit10=1 {
|
|
build RSsrc;
|
|
JXWritePC(RSsrc);
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
call [pc];
|
|
}
|
|
@else
|
|
# 0000 00ss sss0 0000 dddd d1hh hh00 1001
|
|
:jalr.hb RD, RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & RD & bit10=1 {
|
|
RD = inst_next;
|
|
delayslot( 1 );
|
|
tmp:$(ADDRSIZE) = 0;
|
|
ValCast(tmp,RSsrc);
|
|
call [tmp];
|
|
}
|
|
:jalr.hb RSsrc is $(AMODE) & prime=0 & fct=9 & RSsrc & rt=0 & rd=0x1F & bit10=1 {
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
tmp:$(ADDRSIZE) = 0;
|
|
ValCast(tmp,RSsrc);
|
|
call [tmp];
|
|
}
|
|
@endif
|
|
|
|
@ifdef ISA_VARIANT
|
|
# 0000 00ss sss0 0000 0000 0hhh hh00 1000
|
|
:jr RSsrc is $(AMODE) & prime=0 & ((REL6=0 & fct=8) | (REL6=1 & fct=0x09)) & RSsrc & rt=0 & rd=0 {
|
|
build RSsrc;
|
|
JXWritePC(RSsrc);
|
|
delayslot(1);
|
|
goto [pc];
|
|
}
|
|
@else
|
|
# 0000 00ss sss0 0000 0000 0hhh hh00 1000
|
|
:jr RSsrc is $(AMODE) & prime=0 & ((REL6=0 & fct=8) | (REL6=1 & fct=0x09)) & RSsrc & rt=0 & rd=0 {
|
|
delayslot(1);
|
|
tmp:$(ADDRSIZE) = 0;
|
|
ValCast(tmp,RSsrc);
|
|
goto [tmp];
|
|
}
|
|
@endif
|
|
@ifdef ISA_VARIANT
|
|
# 0000 00ss sss0 0000 0000 01hh hh00 1000
|
|
:jr.hb RSsrc is $(AMODE) & prime=0 & ((REL6=0 & fct=8) | (REL6=1 & fct=0x09)) & RSsrc & rt=0 & rd=0 & bit10=1 {
|
|
build RSsrc;
|
|
JXWritePC(RSsrc);
|
|
delayslot(1);
|
|
goto [pc];
|
|
}
|
|
@else
|
|
# 0000 00ss sss0 0000 0000 01hh hh00 1000
|
|
:jr.hb RSsrc is $(AMODE) & prime=0 & ((REL6=0 & fct=8) | (REL6=1 & fct=0x09)) & RSsrc & rt=0 & rd=0 & bit10=1 {
|
|
delayslot(1);
|
|
tmp:$(ADDRSIZE) = 0;
|
|
ValCast(tmp,RSsrc);
|
|
goto [tmp];
|
|
}
|
|
@endif
|
|
|
|
# Special case of JR
|
|
# 0000 0011 1110 0000 0000 0hhh hh00 1000
|
|
@ifdef ISA_VARIANT
|
|
:jr ra is $(AMODE) & prime=0 & ((REL6=0 & fct=8) | (REL6=1 & fct=0x09)) & rs=0x1F & ra & rt=0 & rd=0 & sa=0 {
|
|
JXWritePC(ra);
|
|
delayslot(1);
|
|
return[pc];
|
|
}
|
|
@else
|
|
:jr ra is $(AMODE) & prime=0 & ((REL6=0 & fct=8) | (REL6=1 & fct=0x09)) & rs=0x1F & ra & rt=0 & rd=0 & sa=0 {
|
|
delayslot(1);
|
|
return[ra];
|
|
}
|
|
@endif
|
|
|
|
|
|
|
|
|
|
# 1000 00bb bbbt tttt iiii iiii iiii iiii
|
|
:lb RT, OFF_BASE is $(AMODE) & prime=0x20 & OFF_BASE & RT {
|
|
RT = sext(*[ram]:1 OFF_BASE);
|
|
}
|
|
|
|
:lbe RT, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x2C & bit6=0 & OFF_BASER6 & RT {
|
|
RT = sext(*[ram]:1 OFF_BASER6);
|
|
}
|
|
|
|
# 1001 00bb bbbt tttt iiii iiii iiii iiii
|
|
:lbu RT, OFF_BASE is $(AMODE) & prime=0x24 & OFF_BASE & RT {
|
|
RT = zext( *[ram]:1 OFF_BASE );
|
|
}
|
|
|
|
:lbue RT, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x28 & bit6=0 & OFF_BASER6 & RT {
|
|
RT = zext( *[ram]:1 OFF_BASER6 );
|
|
}
|
|
|
|
# 1000 01bb bbbt tttt iiii iiii iiii iiii
|
|
:lh RT, OFF_BASE is $(AMODE) & prime=0x21 & OFF_BASE & RT {
|
|
RT = sext( *[ram]:2 OFF_BASE );
|
|
}
|
|
|
|
:lhe RT, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x2D & bit6=0 & OFF_BASER6 & RT {
|
|
RT = sext( *[ram]:2 OFF_BASER6 );
|
|
}
|
|
|
|
# 1001 01bb bbbt tttt iiii iiii iiii iiii
|
|
:lhu RT, OFF_BASE is $(AMODE) & prime=0x25 & OFF_BASE & RT {
|
|
RT = zext( *[ram]:2 OFF_BASE );
|
|
}
|
|
|
|
:lhue RT, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x29 & bit6=0 & OFF_BASER6 & RT {
|
|
RT = zext( *[ram]:2 OFF_BASER6 );
|
|
}
|
|
|
|
:lle RT, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x2E & bit6=0 & OFF_BASER6 & RT {
|
|
RT = sext(*[ram]:4 OFF_BASER6);
|
|
}
|
|
|
|
# 1000 11bb bbbt tttt iiii iiii iiii iiii
|
|
:lw RT, OFF_BASE is $(AMODE) & prime=0x23 & OFF_BASE & RT {
|
|
RT = sext( *[ram]:4 OFF_BASE );
|
|
}
|
|
|
|
:lwe RT, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x2F & bit6=0 & OFF_BASER6 & RT {
|
|
RT = sext( *[ram]:4 OFF_BASER6 );
|
|
}
|
|
|
|
:lbx RD, INDEX_BASE is $(AMODE) & prime=0x1F & RD & fct=10 & fct2=22 & INDEX_BASE {
|
|
RD = sext(*[ram]:1 INDEX_BASE);
|
|
}
|
|
|
|
:lbux RD, INDEX_BASE is $(AMODE) & prime=0x1F & RD & fct=10 & fct2=6 & INDEX_BASE {
|
|
RD = zext(*[ram]:1 INDEX_BASE);
|
|
}
|
|
|
|
@ifdef MIPS64
|
|
:ldx RD, INDEX_BASE is $(AMODE) & prime=0x1F & RD & fct=10 & fct2=8 & INDEX_BASE {
|
|
RD = *[ram]:8 INDEX_BASE;
|
|
}
|
|
@endif
|
|
|
|
:lhx RD, INDEX_BASE is $(AMODE) & prime=0x1F & RD & fct=10 & fct2=4 & INDEX_BASE {
|
|
RD = sext(*[ram]:2 INDEX_BASE);
|
|
}
|
|
|
|
:lhux RD, INDEX_BASE is $(AMODE) & prime=0x1F & RD & fct=10 & fct2=20 & INDEX_BASE {
|
|
RD = zext(*[ram]:2 INDEX_BASE);
|
|
}
|
|
|
|
:lwx RD, INDEX_BASE is $(AMODE) & prime=0x1F & RD & fct=10 & fct2=0 & INDEX_BASE {
|
|
@ifdef MIPS64
|
|
RD = sext(*[ram]:4 INDEX_BASE);
|
|
@else
|
|
RD = *[ram]:4 INDEX_BASE;
|
|
@endif
|
|
}
|
|
|
|
@ifdef MIPS64
|
|
:lwux RD, INDEX_BASE is $(AMODE) & prime=0x1F & RD & fct=10 & fct2=16 & INDEX_BASE {
|
|
RD = zext(*[ram]:4 INDEX_BASE);
|
|
}
|
|
@endif
|
|
|
|
# 0100 0000 000t tttt dddd d000 0000 0sss
|
|
:mfc0 RT, RD0 is $(AMODE) & prime=0x10 & copop=0 & RT & RD0 & zero6=0 {
|
|
RT = sext( RD0:$(SIZETO4) );
|
|
}
|
|
|
|
# 0100 1000 000t tttt iiii iiii iiii iiii
|
|
:mfc2 RT, immed is $(AMODE) & prime=0x12 & copop=0 & RT & immed {
|
|
tmp:$(REGSIZE) = getCopReg(2:1, immed:4);
|
|
RT = sext( tmp );
|
|
}
|
|
|
|
# 0100 1000 011t tttt iiii iiii iiii iiii
|
|
:mfhc2 RT, immed is $(AMODE) & prime=0x12 & copop=3 & RT & fs & immed {
|
|
tmp:$(REGSIZE) = getCopReg(2:1, immed:4);
|
|
RT = sext(tmp >> 32);
|
|
}
|
|
|
|
# Special case of ADDIU
|
|
# 0010 0100 000t tttt iiii iiii iiii iiii
|
|
:li RT, simmed is $(AMODE) & prime=9 & rs=0 & RT & simmed {
|
|
RT = simmed;
|
|
}
|
|
# Special case of ADDU
|
|
# 0000 0000 000t tttt dddd d000 0010 0001
|
|
:move RD, RTsrc is $(AMODE) & prime=0 & fct=0x21 & rs=0 & RD & RTsrc & sa=0 {
|
|
RD = RTsrc;
|
|
}
|
|
# Special case of ADDU
|
|
# 0000 00ss sss0 0000 dddd d000 0010 0001
|
|
:move RD, RSsrc is $(AMODE) & prime=0 & fct=0x21 & RSsrc & rt=0 & RD & sa=0 {
|
|
RD = RSsrc;
|
|
}
|
|
|
|
# 0100 0000 100t tttt dddd d000 0000 0sss
|
|
:mtc0 RTsrc, RD0, sel is $(AMODE) & prime=0x10 & copop=4 & RTsrc & RD0 & zero6=0 & sel {
|
|
setCopReg(0:1, RD0, RTsrc, sel:1);
|
|
}
|
|
# 0100 1000 100t tttt iiii iiii iiii iiii
|
|
:mtc2 RTsrc, immed is $(AMODE) & prime=0x12 & copop=4 & RTsrc & immed {
|
|
setCopReg(2:1, immed:4, RTsrc);
|
|
}
|
|
|
|
:mthc0 RTsrc, RD0, sel is $(AMODE) & prime=0x10 & copop=6 & RTsrc & RD0 & zero6=0 & sel {
|
|
setCopReg(0:1, RD0, RTsrc, sel:1);
|
|
}
|
|
|
|
# 0100 1000 111t tttt iiii iiii iiii iiii
|
|
:mthc2 RTsrc, immed is $(AMODE) & prime=0x12 & copop=0x07 & RTsrc & immed {
|
|
arg:4 = immed;
|
|
tmp:4 = RTsrc:$(SIZETO4);
|
|
low:4 = getCopReg(2:1, arg);
|
|
val:8 = (zext(tmp) << 32) + zext(low);
|
|
setCopReg(2:1, arg, val);
|
|
}
|
|
|
|
:nal is $(AMODE) & REL6=0 & prime=1 & cond=0x10 & zero21=0 {
|
|
delayslot(1);
|
|
ra = inst_next;
|
|
}
|
|
|
|
# 0000 0000 0000 0000 0000 0000 0000 0000
|
|
:nop is $(AMODE) & prime=0 & rs=0 & rt=0 & rd=0 & sa=0 & fct=0 {
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0010 0111
|
|
:nor RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x27 & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = ~(RSsrc | RTsrc);
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0010 0101
|
|
:or RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x25 & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = RSsrc | RTsrc;
|
|
}
|
|
# 0011 01ss ssst tttt iiii iiii iiii iiii
|
|
:ori RT, RSsrc, immed is $(AMODE) & prime=0xD & RSsrc & RT & immed {
|
|
RT = RSsrc | immed;
|
|
}
|
|
|
|
:pause is $(AMODE) & prime=0 & szero=0 & fct=0 & fct2=0x05 {
|
|
wait();
|
|
}
|
|
|
|
:pref hint, OFF_BASE is $(AMODE) & prime=0x33 & hint & OFF_BASE {
|
|
prefetch(OFF_BASE, hint:1);
|
|
}
|
|
|
|
:prefe hint, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x23 & bit6=0 & OFF_BASER6 & hint {
|
|
prefetch(OFF_BASER6, hint:1);
|
|
}
|
|
|
|
# 0111 1100 000t tttt dddd d000 0011 1011
|
|
:rdhwr RT, RDsrc is $(AMODE) & prime=0x1F & rs=0 & fct2=0 & fct=0x3B & RT & RDsrc {
|
|
RT = getHWRegister(RDsrc);
|
|
}
|
|
|
|
# 0100 0001 010t tttt dddd d000 0000 0000
|
|
:rdpgpr RD, RT is $(AMODE) & prime=0x10 & rs=10 & bigfunct=0 & RD & RT {
|
|
RD = getShadow(RT);
|
|
}
|
|
|
|
# 0000 0000 001t tttt dddd daaa aa00 0010
|
|
:rotr RD32, RT32src, sa is $(AMODE) & prime=0 & zero1=0 & bit21=1 & fct=2 & RD32 & RT32src & sa & RD {
|
|
tmp1:4 = RT32src >> sa;
|
|
tmp2:4 = RT32src << (32 - sa);
|
|
RD32 = tmp1 + tmp2;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0100 0110
|
|
:rotrv RD32, RT32src, RS32src is $(AMODE) & prime=0 & zero2=0 & bit6=1 & fct=6 & RD32 & RT32src & RS32src & RD {
|
|
shift:4 = RS32src & 0x1f;
|
|
tmp1:4 = RT32src >> shift;
|
|
tmp2:4 = RT32src << (32 - shift);
|
|
RD32 = tmp1 + tmp2;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
|
|
# 1010 00bb bbbt tttt iiii iiii iiii iiii
|
|
:sb RTsrc, OFF_BASE is $(AMODE) & prime=0x28 & OFF_BASE & RTsrc {
|
|
*[ram]:1 OFF_BASE = RTsrc:1;
|
|
}
|
|
|
|
:sbe RTsrc, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x1C & bit6=0 & OFF_BASER6 & RTsrc {
|
|
*[ram]:1 OFF_BASER6 = RTsrc:1;
|
|
}
|
|
|
|
:sce RTsrc, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x1E & bit6=0 & OFF_BASER6 & RTsrc {
|
|
*[ram]:4 OFF_BASER6 = RTsrc:$(SIZETO4);
|
|
RTsrc = 1;
|
|
}
|
|
|
|
# 0111 00cc cccc cccc cccc cccc cc11 1111
|
|
:sdbbp breakcode is $(AMODE) & prime=0x1C & fct=0x3F & breakcode {
|
|
signalDebugBreakpointException();
|
|
}
|
|
|
|
@ifndef COPR_C
|
|
# 1111 10bb bbbt tttt iiii iiii iiii iiii
|
|
:sdc2 RTsrc, OFF_BASE is $(AMODE) & prime=0x3E & OFF_BASE & RTsrc {
|
|
*[ram]:8 OFF_BASE = getCopReg(2:1, RTsrc);
|
|
}
|
|
@endif
|
|
|
|
# 0111 1100 000t tttt dddd d100 0010 0000
|
|
:seb RD, RTsrc is $(AMODE) & prime=0x1F & rs=0 & fct2=0x10 & fct=0x20 & RD & RTsrc {
|
|
RD = sext( RTsrc:1 );
|
|
}
|
|
# 0111 1100 000t tttt dddd d110 0010 0000
|
|
:seh RD, RTsrc is $(AMODE) & prime=0x1F & rs=0 & fct2=0x18 & fct=0x20 & RD & RTsrc {
|
|
RD = sext( RTsrc:2 );
|
|
}
|
|
# 1010 01bb bbbt tttt iiii iiii iiii iiii
|
|
:sh RTsrc, OFF_BASE is $(AMODE) & prime=0x29 & OFF_BASE & RTsrc {
|
|
*[ram]:2 OFF_BASE = RTsrc:2;
|
|
}
|
|
|
|
:she RTsrc, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x1D & bit6=0 & OFF_BASER6 & RTsrc {
|
|
*[ram]:2 OFF_BASER6 = RTsrc:2;
|
|
}
|
|
|
|
# 0000 0000 000t tttt dddd daaa aa00 0000
|
|
:sll RD32, RT32src, sa is $(AMODE) & prime=0 & fct=0 & rs=0 & RD32 & RT32src & sa & RD {
|
|
RD32 = RT32src << sa;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0000 0100
|
|
:sllv RD32, RT32src, RS32src is $(AMODE) & prime=0 & fct=4 & RS32src & RT32src & RD32 & sa=0 & RD {
|
|
shift:4 = RS32src & 0x1f;
|
|
RD32 = RT32src << shift;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0010 1010
|
|
:slt RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x2A & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = zext( RSsrc s< RTsrc );
|
|
}
|
|
# 0010 10ss ssst tttt iiii iiii iiii iiii
|
|
:slti RT, RSsrc, simmed is $(AMODE) & prime=10 & RSsrc & RT & simmed {
|
|
RT = zext( RSsrc s< simmed );
|
|
}
|
|
# 0010 11ss ssst tttt iiii iiii iiii iiii
|
|
:sltiu RT, RSsrc, simmed is $(AMODE) & prime=0xB & RSsrc & RT & simmed {
|
|
RT = zext( RSsrc < simmed );
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0010 1011
|
|
:sltu RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x2B & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = zext( RSsrc < RTsrc );
|
|
}
|
|
|
|
# 0000 0000 000t tttt dddd daaa aa00 0011
|
|
:sra RD32, RT32src, sa is $(AMODE) & prime=0 & fct=3 & rs=0 & RT32src & RD32 & sa & RD {
|
|
RD32 = RT32src s>> sa;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0000 0111
|
|
:srav RD32, RT32src, RS32src is $(AMODE) & prime=0 & fct=7 & RS32src & RT32src & RD32 & sa=0 & RD {
|
|
shift:4 = RS32src & 0x1f;
|
|
RD32 = RT32src s>> shift;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
# 0000 0000 000t tttt dddd daaa aa00 0010
|
|
:srl RD32, RT32src, sa is $(AMODE) & prime=0 & fct=2 & rs=0 & RT32src & RD32 & sa & RD {
|
|
RD32 = RT32src >> sa;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0000 0110
|
|
:srlv RD32, RT32src, RS32src is $(AMODE) & prime=0 & fct=6 & RS32src & RT32src & RD32 & sa=0 & RD {
|
|
shift:4 = RS32src & 0x1f;
|
|
RD32 = RT32src >> shift;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
|
|
# 0000 0000 0000 0000 0000 0000 0100 0000
|
|
:ssnop is $(AMODE) & prime=0 & rs=0 & rt=0 & rd=0 & sa=1 & fct=0 {
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0010 0010
|
|
:sub RD32, RS32src, RT32src is $(AMODE) & prime=0 & fct=0x22 & RS32src & RT32src & RD32 & sa=0 & RD {
|
|
RD32 = RS32src - RT32src;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0010 0011
|
|
:subu RD32, RS32src, RT32src is $(AMODE) & prime=0 & fct=0x23 & RS32src & RT32src & RD32 & sa=0 & RD {
|
|
RD32 = RS32src - RT32src;
|
|
@ifdef MIPS64
|
|
RD = sext(RD32);
|
|
@endif
|
|
}
|
|
|
|
# 1010 11bb bbbt tttt iiii iiii iiii iiii
|
|
:sw RTsrc, OFF_BASE is $(AMODE) & prime=0x2B & OFF_BASE & RTsrc {
|
|
*[ram]:4 OFF_BASE = RTsrc:$(SIZETO4);
|
|
}
|
|
|
|
@ifndef COPR_C
|
|
# 1110 10bb bbbt tttt iiii iiii iiii iiii
|
|
:swc2 hint, OFF_BASE is $(AMODE) & prime=0x3A & OFF_BASE & hint {
|
|
tmp:4 = getCopReg(2:1, hint:4);
|
|
*[ram]:4 OFF_BASE = tmp;
|
|
}
|
|
@endif
|
|
|
|
:swe RTsrc, OFF_BASER6 is $(AMODE) & prime=0x1F & fct=0x1F & bit6=0 & OFF_BASER6 & RTsrc {
|
|
*[ram]:4 OFF_BASER6 = RTsrc:$(SIZETO4);
|
|
}
|
|
|
|
define pcodeop SYNC;
|
|
|
|
# 0000 0000 0000 0000 0000 0yyy yy00 1111
|
|
:sync scalar is $(AMODE) & prime=0 & fct=0xF & szero=0 & stype [ scalar = stype + 0; ] {
|
|
SYNC(scalar:1);
|
|
}
|
|
|
|
# 0000 01bb bbb1 1111 iiii iiii iiii iiii
|
|
:synci OFF_BASE is $(AMODE) & prime=1 & OFF_BASE & synci=0x1F {
|
|
}
|
|
|
|
# 0000 00cc cccc cccc cccc cccc cc00 1100
|
|
:syscall is $(AMODE) & prime=0 & fct=0xC & breakcode {
|
|
tmp:4=breakcode;
|
|
syscall(tmp);
|
|
}
|
|
|
|
# 0000 00ss ssst tttt cccc cccc cc11 0100
|
|
:teq RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x34 & RSsrc & RTsrc & code {
|
|
if (RSsrc != RTsrc) goto <done>;
|
|
tmp:2=code;
|
|
trap(tmp);
|
|
<done>
|
|
}
|
|
# 0000 00ss ssst tttt cccc cccc cc11 0000
|
|
:tge RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x30 & RSsrc & RTsrc & code {
|
|
if (RSsrc < RTsrc) goto <done>;
|
|
tmp:2=code;
|
|
trap(tmp);
|
|
<done>
|
|
}
|
|
# 0000 00ss ssst tttt cccc cccc cc11 0001
|
|
:tgeu RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x31 & RSsrc & RTsrc & code {
|
|
if (RSsrc < RTsrc) goto <done>;
|
|
tmp:2=code;
|
|
trap(tmp);
|
|
<done>
|
|
}
|
|
|
|
:tlbinv is $(AMODE) & prime=0x10 & bit25=1 & copfill=0x00 & fct=0x03 {
|
|
TLB_invalidate(Index, EntryHi);
|
|
}
|
|
|
|
:tlbinvf is $(AMODE) & prime=0x10 & bit25=1 & copfill=0x00 & fct=0x04 {
|
|
TLB_invalidate_flush(Index);
|
|
}
|
|
|
|
:tlbp is $(AMODE) & prime=0x10 & bit25=1 & copfill=0x00 & fct=0x08 {
|
|
Index = TLB_probe_for_matching_entry(EntryHi);
|
|
}
|
|
|
|
:tlbr is $(AMODE) & prime=0x10 & bit25=1 & copfill=0x00 & fct=0x01 {
|
|
EntryHi = TLB_read_indexed_entryHi(Index);
|
|
EntryLo0 = TLB_read_indexed_entryLo0(Index);
|
|
EntryLo1 = TLB_read_indexed_entryLo1(Index);
|
|
PageMask = TLB_read_indexed_entryLo1(Index);
|
|
}
|
|
|
|
:tlbwi is $(AMODE) & prime=0x10 & bit25=1 & copfill=0x00 & fct=0x02 {
|
|
TLB_write_indexed_entry(Index, EntryHi, EntryLo0, EntryLo1, PageMask);
|
|
}
|
|
|
|
:tlbwr is $(AMODE) & prime=0x10 & bit25=1 & copfill=0x00 & fct=0x06 {
|
|
TLB_write_random_entry(Random, EntryHi, EntryLo0, EntryLo1, PageMask);
|
|
}
|
|
|
|
# 0000 00ss ssst tttt cccc cccc cc11 0010
|
|
:tlt RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x32 & RSsrc & RTsrc & code {
|
|
if (RSsrc s>= RTsrc) goto <done>;
|
|
tmp:2=code;
|
|
trap(tmp);
|
|
<done>
|
|
}
|
|
# 0000 00ss ssst tttt cccc cccc cc11 0011
|
|
:tltu RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x33 & RSsrc & RTsrc & code {
|
|
if (RSsrc >= RTsrc) goto <done>;
|
|
tmp:2=code;
|
|
trap(tmp);
|
|
<done>
|
|
}
|
|
# 0000 00ss ssst tttt cccc cccc cc11 0110
|
|
:tne RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x36 & RSsrc & RTsrc & code {
|
|
if (RSsrc == RTsrc) goto <done>;
|
|
tmp:2=code;
|
|
trap(tmp);
|
|
<done>
|
|
}
|
|
|
|
# 0100 001c cccc cccc cccc cccc cc10 0000
|
|
:wait is $(AMODE) & prime=0x10 & fct=0x20 & copfill & bit25=1 {
|
|
tmp:4 = copfill;
|
|
wait(tmp);
|
|
}
|
|
|
|
# 0100 0001 110t tttt dddd d000 0000 0000
|
|
:wrpgpr RD, RTsrc is $(AMODE) & prime=0x10 & format=0xE & RTsrc & RD & bigfunct=0 {
|
|
setShadow(RD, RTsrc);
|
|
}
|
|
|
|
# 0111 1100 000t tttt dddd d000 1010 0000
|
|
:wsbh RD, RTsrc is $(AMODE) & prime=0x1F & format=0 & RTsrc & RD & wsbh=2 & bshfl=0x20 {
|
|
tmp1:$(REGSIZE) = RTsrc & 0xff;
|
|
tmp2:$(REGSIZE) = (RTsrc >> 8) & 0xff;
|
|
tmp3:$(REGSIZE) = (RTsrc >> 16) & 0xff;
|
|
tmp4:$(REGSIZE) = (RTsrc >> 24) & 0xff;
|
|
RD = (tmp3 << 24) | (tmp4 << 16) | (tmp1 << 8) | (tmp2);
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0010 0110
|
|
:xor RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x26 & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = RSsrc ^ RTsrc;
|
|
}
|
|
# 0011 10ss ssst tttt iiii iiii iiii iiii
|
|
:xori RT, RSsrc, immed is $(AMODE) & prime=0xE & RSsrc & RT & immed {
|
|
RT = RSsrc ^ immed;
|
|
}
|
|
|
|
############################
|
|
#
|
|
# MIPS64 Instructions to be included with all MIPS32 processors
|
|
#
|
|
############################
|
|
|
|
## Allow MIPS 64 instructions below for compilers
|
|
## using a 64-bit chip, but really keeping things to 32-bits
|
|
|
|
# Special case of daddu
|
|
# 0000 00ss ssst tttt dddd d000 0010 1101
|
|
:clear RD is $(AMODE) & prime=0 & fct=0x2D & rs=0 & rt=0 & RD & sa=0 {
|
|
RD = 0;
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0010 1100
|
|
:dadd RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x2C & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = RSsrc + RTsrc;
|
|
}
|
|
# 0110 01ss ssst tttt iiii iiii iiii iiii
|
|
:daddiu RT, RSsrc, simmed is $(AMODE) & prime=0x19 & RSsrc & RT & simmed {
|
|
RT = RSsrc + simmed;
|
|
}
|
|
# 0000 00ss ssst tttt dddd d000 0010 1101
|
|
:daddu RD, RSsrc, RTsrc is $(AMODE) & prime=0 & fct=0x2D & RSsrc & RTsrc & RD & sa=0 {
|
|
RD = RSsrc + RTsrc;
|
|
}
|
|
|
|
####
|
|
#
|
|
# Pre-6 semantics
|
|
#
|
|
####
|
|
# 0010 00ss ssst tttt iiii iiii iiii iiii
|
|
:addi RT32, RS32src, simmed is $(AMODE) & REL6=0 & prime=8 & RT32 & RS32src & simmed & RT {
|
|
RT32 = RS32src + simmed;
|
|
@ifdef MIPS64
|
|
RT = sext(RT32);
|
|
@endif
|
|
}
|
|
|
|
# 0000 01ss sss1 0001 iiii iiii iiii iiii
|
|
:bal Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=0x11 & rs=0 & Rel16 {
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
call Rel16;
|
|
}
|
|
|
|
# Special case PIC
|
|
:bal Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=0x11 & rs=0 & off16=1 & Rel16 {
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
goto Rel16;
|
|
}
|
|
|
|
# 0100 1001 000c cc00 iiii iiii iiii iiii
|
|
:bc2f Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc=0 & nd=0 & tf=0 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, 0:1);
|
|
delayslot(1);
|
|
if (tmp != 0) goto inst_next;
|
|
goto Rel16;
|
|
}
|
|
:bc2f cc,Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc & nd=0 & tf=0 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, cc:1);
|
|
delayslot(1);
|
|
if (tmp != 0) goto inst_next;
|
|
goto Rel16;
|
|
}
|
|
# 0100 1001 000c cc10 iiii iiii iiii iiii
|
|
:bc2fl Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc=0 & nd=1 & tf=0 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, 0:1);
|
|
if (tmp != 0) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
:bc2fl cc,Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc & nd=1 & tf=0 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, cc:1);
|
|
if (tmp != 0) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
# 0100 1001 000c cc01 iiii iiii iiii iiii
|
|
:bc2t Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc=0 & nd=0 & tf=1 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, 0:1);
|
|
delayslot(1);
|
|
if (tmp == 0) goto inst_next;
|
|
goto Rel16;
|
|
}
|
|
:bc2t cc,Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc & nd=0 & tf=1 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, cc:1);
|
|
delayslot(1);
|
|
if (tmp == 0) goto inst_next;
|
|
goto Rel16;
|
|
}
|
|
# 0100 1001 000c cc11 iiii iiii iiii iiii
|
|
:bc2tl Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc=0 & nd=1 & tf=1 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, 0:1);
|
|
if (tmp == 0) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
:bc2tl cc,Rel16 is $(AMODE) & REL6=0 & prime=0x12 & copop=8 & cc & nd=1 & tf=1 & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, cc:1);
|
|
if (tmp == 0) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
|
|
# 0101 00ss ssst tttt iiii iiii iiii iiii
|
|
:beql RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=0 & prime=0x14 & RSsrc & RTsrc & Rel16 {
|
|
if (!(RSsrc==RTsrc)) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
|
|
:bgezal RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=0x11 & RSsrc & Rel16 {
|
|
ra = inst_next;
|
|
delayflag:1 = ( RSsrc s>= 0 );
|
|
delayslot( 1 );
|
|
if (!delayflag) goto inst_next;
|
|
call Rel16;
|
|
}
|
|
|
|
# 0000 01ss sss1 0011 iiii iiii iiii iiii
|
|
:bgezall RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=0x13 & RSsrc & Rel16 {
|
|
ra = inst_next;
|
|
if (!(RSsrc s>= 0)) goto inst_next;
|
|
delayslot( 1 );
|
|
call Rel16;
|
|
}
|
|
# 0000 01ss sss0 0011 iiii iiii iiii iiii
|
|
:bgezl RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=3 & RSsrc & Rel16 {
|
|
if (!(RSsrc s>= 0)) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
# 0101 11ss sss0 0000 iiii iiii iiii iiii
|
|
:bgtzl RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=0x17 & cond=0 & RSsrc & Rel16 {
|
|
if (!(RSsrc s> 0)) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
# 0101 10ss sss0 0000 iiii iiii iiii iiii
|
|
:blezl RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=0x16 & cond=0 & RSsrc & Rel16 {
|
|
if (!(RSsrc s<= 0)) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
# 0000 01ss sss1 0000 iiii iiii iiii iiii
|
|
:bltzal RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=0x10 & RSsrc & Rel16 {
|
|
ra = inst_next;
|
|
delayflag:1 = ( RSsrc s< 0 );
|
|
delayslot( 1 );
|
|
if (!delayflag) goto inst_next;
|
|
call Rel16;
|
|
}
|
|
# 0000 01ss sss1 0010 iiii iiii iiii iiii
|
|
:bltzall RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=0x12 & RSsrc & Rel16 {
|
|
ra = inst_next;
|
|
if (!(RSsrc s< 0)) goto inst_next;
|
|
delayslot(1);
|
|
call Rel16;
|
|
}
|
|
# 0000 01ss sss0 0010 iiii iiii iiii iiii
|
|
:bltzl RSsrc, Rel16 is $(AMODE) & REL6=0 & prime=1 & cond=2 & RSsrc & Rel16 {
|
|
if (!(RSsrc s< 0)) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
# 0101 01ss ssst tttt iiii iiii iiii iiii
|
|
:bnel RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=0 & prime=0x15 & RSsrc & RTsrc & Rel16 {
|
|
if (!(RSsrc!=RTsrc)) goto inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
|
|
# 0111 00ss ssst tttt dddd d000 0010 0001
|
|
:clo RD, RSsrc is $(AMODE) & REL6=0 & prime=0x1C & sa=0x0 & fct=0x21 & RD & RSsrc {
|
|
# Count leading ones in a word
|
|
RD = countLeadingOnes( RSsrc );
|
|
}
|
|
|
|
# 0111 00ss ssst tttt dddd d000 0010 0000
|
|
:clz RD, RSsrc is $(AMODE) & REL6=0 & prime=0x1C & sa=0x0 & fct=0x20 & RD & RSsrc {
|
|
# Count leading zeros in a word
|
|
RD = countLeadingZeros( RSsrc );
|
|
}
|
|
|
|
# 0000 00ss ssst tttt 0000 0000 0001 1010
|
|
:div RS32src, RT32src is $(AMODE) & REL6=0 & prime=0 & fct=0x1A & RS32src & RT32src & rd=0 & sa=0 {
|
|
lo = sext(RS32src s/ RT32src);
|
|
hi = sext(RS32src s% RT32src);
|
|
}
|
|
# 0000 00ss ssst tttt 0000 0000 0001 1011
|
|
:divu RS32src, RT32src is $(AMODE) & REL6=0 & prime=0 & fct=0x1B & RS32src & RT32src & rd=0 & sa=0 {
|
|
lo = sext(RS32src / RT32src);
|
|
hi = sext(RS32src % RT32src);
|
|
}
|
|
@ifdef ISA_VARIANT
|
|
# 0111 01aa aaaa aaaa aaaa aaaa aaaa aaaa
|
|
:jalx Abs26 is $(AMODE) & REL6=0 & prime=0x1D & Abs26 [ ISA_MODE = 1; globalset(Abs26, ISA_MODE);] {
|
|
ra = inst_next;
|
|
delayslot( 1 );
|
|
ISAModeSwitch = 1;
|
|
call Abs26;
|
|
}
|
|
@endif
|
|
|
|
@ifndef COPR_C
|
|
# 1101 10bb bbbt tttt iiii iiii iiii iiii
|
|
:ldc2 rt, OFF_BASE is $(AMODE) & REL6=0 & prime=0x36 & OFF_BASE & rt {
|
|
setCopReg(2:1, rt, *[ram]:8 OFF_BASE);
|
|
}
|
|
@endif
|
|
|
|
# 1100 00bb bbbt tttt iiii iiii iiii iiii
|
|
:ll RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x30 & OFF_BASE & RT {
|
|
RT = sext(*[ram]:4 OFF_BASE);
|
|
}
|
|
|
|
# 0011 1100 000t tttt iiii iiii iiii iiii
|
|
:lui RT, immed is $(AMODE) & REL6=0 & prime=0xF & rs=0 & RT & immed {
|
|
tmp:4 = immed << 16;
|
|
RT = sext(tmp);
|
|
}
|
|
|
|
@ifndef COPR_C
|
|
# 1100 10bb bbbt tttt iiii iiii iiii iiii
|
|
:lwc2 rt, OFF_BASE is $(AMODE) & REL6=0 & prime=0x32 & OFF_BASE & rt {
|
|
setCopReg( 2:1, rt, *[ram]:4 OFF_BASE );
|
|
}
|
|
@endif
|
|
|
|
@if ENDIAN == "big"
|
|
# 1000 10bb bbbt tttt iiii iiii iiii iiii
|
|
:lwl RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x22 & OFF_BASE & RT & RTsrc {
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff >> ((4-shft) * 8));
|
|
valLoad:4 = *(addr) << (shft * 8);
|
|
RT = sext( valLoad | valOrig );
|
|
}
|
|
|
|
# 1001 10bb bbbt tttt iiii iiii iiii iiii
|
|
:lwr RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x26 & OFF_BASE & RT & RTsrc {
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff << ((shft+1) * 8));
|
|
valLoad:4 = *(addr) >> ((3-shft) * 8);
|
|
RT = sext( valOrig | valLoad );
|
|
}
|
|
:lwle RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x19 & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff >> ((4-shft) * 8));
|
|
valLoad:4 = *(addr) << (shft * 8);
|
|
RT = sext( valLoad | valOrig );
|
|
}
|
|
|
|
:lwre RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x1A & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff << ((shft+1) * 8));
|
|
valLoad:4 = *(addr) >> ((3-shft) * 8);
|
|
RT = sext( valOrig | valLoad );
|
|
}
|
|
@else
|
|
:lwl RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x22 & OFF_BASE & RT & RTsrc {
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff >> ((shft+1)* 8));
|
|
valLoad:4 = *(addr) << ((3-shft) * 8);
|
|
RT = sext( valLoad | valOrig );
|
|
}
|
|
|
|
# 1001 10bb bbbt tttt iiii iiii iiii iiii
|
|
:lwr RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x26 & OFF_BASE & RT & RTsrc {
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff << ((4-shft)* 8));
|
|
valLoad:4 = *(addr) >> (shft * 8);
|
|
RT = sext( valOrig | valLoad );
|
|
}
|
|
:lwle RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x19 & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff >> ((shft+1)* 8));
|
|
valLoad:4 = *(addr) << ((3-shft) * 8);
|
|
RT = sext( valLoad | valOrig );
|
|
}
|
|
|
|
:lwre RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x1A & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = RTsrc:$(SIZETO4) & (0xffffffff << ((4-shft)* 8));
|
|
valLoad:4 = *(addr) >> (shft * 8);
|
|
RT = sext( valOrig | valLoad );
|
|
}
|
|
@endif
|
|
|
|
# lwl and lwr almost always come in pairs.
|
|
# When the analyzer does finds a matching lwl/lwr pair, the pcode is simplified so that
|
|
# lwl does all the loading while lwr is a no-op
|
|
@if ENDIAN == "big"
|
|
:lwl RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x22 & OFF_BASE & RT & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 1; globalset(inst_next, PAIR_INSTRUCTION_FLAG);] {
|
|
RT = sext( *[ram]:4 OFF_BASE );
|
|
}
|
|
:lwr RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x26 & OFF_BASE & RT & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 0; ] {
|
|
}
|
|
@else
|
|
:lwl RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x22 & OFF_BASE & RT & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 1; globalset(inst_next, PAIR_INSTRUCTION_FLAG);] {
|
|
}
|
|
:lwr RT, OFF_BASE is $(AMODE) & REL6=0 & prime=0x26 & OFF_BASE & RT & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 0; ] {
|
|
RT = sext( *[ram]:4 OFF_BASE );
|
|
}
|
|
@endif
|
|
|
|
# 0111 00ss ssst tttt 000a a000 0000 0000
|
|
:madd RS32src, RT32src is $(AMODE) & REL6=0 & prime=0x1C & zero1315=0x0 & fct2=0x0 & fct=0x0 & RS32src & RT32src & achi & aclo {
|
|
tmp1:8 = sext(RS32src);
|
|
tmp2:8 = sext(RT32src);
|
|
prod:8 = tmp1 * tmp2;
|
|
aclo = aclo & 0xffffffff; # Make sure any upper bits of lo don't contribute to sum
|
|
sum:8 = (zext(achi) << 32) + zext(aclo) + prod;
|
|
aclo = sext(sum:4);
|
|
sum = sum >> 32;
|
|
achi = sext(sum:4);
|
|
}
|
|
|
|
# 0111 00ss ssst tttt 000a a000 0000 0001
|
|
:maddu RS32src, RT32src is $(AMODE) & REL6=0 & prime=0x1C & zero1315=0x0 & fct2=0x0 & fct=0x01 & RS32src & RT32src & achi & aclo {
|
|
tmp1:8 = zext(RS32src);
|
|
tmp2:8 = zext(RT32src);
|
|
prod:8 = tmp1 * tmp2;
|
|
aclo = aclo & 0xffffffff; # Make sure any upper bits of lo don't contribute to sum
|
|
sum:8 = (zext(achi) << 32) + zext(aclo) + prod;
|
|
aclo = sext(sum:4);
|
|
sum = sum >> 32;
|
|
achi = sext(sum:4);
|
|
}
|
|
|
|
# 0000 0000 0aa0 0000 dddd d000 0001 0000
|
|
:mfhi RD is $(AMODE) & REL6=0 & prime=0 & fct=0x10 & RD & zero5=0 & zero1620=0 & zero2325=0 & acfhi {
|
|
RD = acfhi;
|
|
}
|
|
|
|
# 0000 0000 0aa0 0000 dddd d000 0001 0010
|
|
:mflo RD is $(AMODE) & REL6=0 & prime=0 & fct=0x12 & RD & zero5=0 & zero1620=0 & zero2325=0 & acflo {
|
|
RD = acflo;
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0000 1011
|
|
:movn RD, RSsrc, RTsrc is $(AMODE) & REL6=0 & prime=0 & zero5=0 & fct=0xB & RD & RSsrc & RTsrc {
|
|
if (RTsrc == 0) goto <done>;
|
|
RD = RSsrc;
|
|
<done>
|
|
}
|
|
|
|
# 0000 00ss ssst tttt dddd d000 0000 1010
|
|
:movz RD, RSsrc, RTsrc is $(AMODE) & REL6=0 & prime=0 & zero5=0 & fct=10 & RD & RSsrc & RTsrc {
|
|
if (RTsrc != 0) goto <done>; # We can't use goto inst_next because it fails if we are in a delay slot
|
|
RD = RSsrc;
|
|
<done>
|
|
}
|
|
|
|
|
|
# 0111 00ss ssst tttt 000a a000 0000 0100
|
|
:msub RS32src, RT32src is $(AMODE) & REL6=0 & prime=0x1C & fct2=0 & fct=0x04 & RS32src & RT32src & zero1315=0 & aclo & achi {
|
|
tmp1:8 = sext(RS32src);
|
|
tmp2:8 = sext(RT32src);
|
|
prod:8 = tmp1 * tmp2;
|
|
aclo = aclo & 0xffffffff; # Make sure any upper bits of lo don't contribute to sum
|
|
sum:8 = (zext(achi) << 32) + zext(aclo) - prod;
|
|
aclo = sext(sum:4);
|
|
sum = sum >> 32;
|
|
achi = sext(sum:4);
|
|
}
|
|
|
|
# 0111 00ss ssst tttt 000a a000 0000 0101
|
|
:msubu RS32src, RT32src is $(AMODE) & REL6=0 & prime=0x1C & fct2=0 & fct=0x05 & RS32src & RT32src & zero1315=0 & aclo & achi {
|
|
tmp1:8 = zext(RS32src);
|
|
tmp2:8 = zext(RT32src);
|
|
prod:8 = tmp1 * tmp2;
|
|
aclo = aclo & 0xffffffff; # Make sure any upper bits of lo don't contribute to sum
|
|
sum:8 = (zext(achi) << 32) + zext(aclo) - prod;
|
|
aclo = sext(sum:4);
|
|
sum = sum >> 32;
|
|
achi = sext(sum:4);
|
|
}
|
|
|
|
# 0000 00ss sss0 0000 000a a000 0001 0001
|
|
:mthi RSsrc is $(AMODE) & REL6=0 & prime=0 & fct=0x11 & RSsrc & zero5=0 & zero1320=0 & achi {
|
|
achi = RSsrc;
|
|
}
|
|
|
|
# 0000 00ss sss0 0000 000a a000 0001 0011
|
|
:mtlo RSsrc is $(AMODE) & REL6=0 & prime=0 & fct=0x13 & RSsrc & zero5=0 & zero1320=0 & aclo {
|
|
aclo = RSsrc;
|
|
}
|
|
|
|
# 0111 00ss ssst tttt dddd d000 0000 0010
|
|
:mul RD, RS32src, RT32src is $(AMODE) & REL6=0 & prime=0x1C & sa=0x0 & fct=0x02 & RD & RS32src & RT32src {
|
|
tmp1:8 = sext( RS32src );
|
|
tmp2:8 = sext( RT32src );
|
|
prod:8 = tmp1 * tmp2;
|
|
RD = sext( prod:4 );
|
|
}
|
|
|
|
# 0000 00ss ssst tttt 000a a000 0001 1000
|
|
:mult RS32src, RT32src is $(AMODE) & REL6=0 & prime=0 & fct=0x18 & RS32src & RT32src & zero5=0 & zero1315=0 & aclo & achi {
|
|
tmp1:8 = sext( RS32src );
|
|
tmp2:8 = sext( RT32src );
|
|
prod:8 = tmp1 * tmp2;
|
|
aclo = sext(prod:4);
|
|
prod = prod >> 32;
|
|
achi = sext(prod:4);
|
|
}
|
|
|
|
# 0000 00ss ssst tttt 000a a000 0001 1001
|
|
:multu RS32src, RT32src is $(AMODE) & REL6=0 & prime=0 & fct=0x19 & RS32src & RT32src & zero5=0 & zero1315=0 & aclo & achi {
|
|
tmp1:8 = zext( RS32src );
|
|
tmp2:8 = zext( RT32src );
|
|
prod:8 = tmp1 * tmp2;
|
|
aclo = sext(prod:4);
|
|
prod = prod >> 32;
|
|
achi = sext(prod:4);
|
|
}
|
|
|
|
# 0100 0110 110t tttt ssss sddd dd10 1100
|
|
:pll.ps fd, fs, ft is $(AMODE) & REL6=0 & prime=0x11 & format=0x16 & fct=0x2C & ft & fs & fd
|
|
unimpl
|
|
|
|
# 0100 0110 110t tttt ssss sddd dd10 1101
|
|
:plu.ps fd, fs, ft is $(AMODE) & REL6=0 & prime=0x11 & format=0x16 & fct=0x2D & ft & fs & fd
|
|
unimpl
|
|
|
|
#:prefx
|
|
|
|
# 0100 0110 110t tttt ssss sddd dd10 1110
|
|
:pul.ps fd, fs, ft is $(AMODE) & REL6=0 & prime=0x11 & format=0x16 & fct=0x2E & fd & fs & ft
|
|
unimpl
|
|
# 0100 0110 110t tttt ssss sddd dd10 1111
|
|
:puu.ps fd, fs, ft is $(AMODE) & REL6=0 & prime=0x11 & format=0x16 & fct=0x2F & fd & fs & ft
|
|
unimpl
|
|
|
|
# 1110 00bb bbbt tttt iiii iiii iiii iiii
|
|
:sc RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x38 & OFF_BASE & RT & RTsrc {
|
|
*[ram]:4 OFF_BASE = RTsrc:$(SIZETO4);
|
|
RT = 1;
|
|
}
|
|
|
|
@if ENDIAN == "big"
|
|
# 1010 10bb bbbt tttt iiii iiii iiii iiii
|
|
:swl RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2A & OFF_BASE & RTsrc {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff << ((4-shft) * 8));
|
|
valStore:4 = tmpRT >> (shft * 8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
# 1011 10bb bbbt tttt iiii iiii iiii iiii
|
|
:swr RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2E & OFF_BASE & RTsrc {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff >> ((shft+1) * 8));
|
|
valStore:4 = tmpRT << ((3-shft)*8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
:swle RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x21 & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff << ((4-shft) * 8));
|
|
valStore:4 = tmpRT >> (shft * 8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
:swre RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x22 & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff >> ((shft+1) * 8));
|
|
valStore:4 = tmpRT << ((3-shft)*8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
|
|
@else
|
|
# 1010 10bb bbbt tttt iiii iiii iiii iiii
|
|
:swl RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2A & OFF_BASE & RTsrc {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff << ((shft+1) * 8));
|
|
valStore:4 = tmpRT >> ((3-shft) * 8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
# 1011 10bb bbbt tttt iiii iiii iiii iiii
|
|
:swr RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2E & OFF_BASE & RTsrc {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASE & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASE - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff >> ((4-shft) * 8));
|
|
valStore:4 = tmpRT << (shft*8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
:swle RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x21 & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff << ((shft+1) * 8));
|
|
valStore:4 = tmpRT >> ((3-shft) * 8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
:swre RTsrc, OFF_BASER6 is $(AMODE) & REL6=0 & prime=0x1F & fct=0x22 & bit6=0 & OFF_BASER6 & RTsrc & RT {
|
|
tmpRT:4 = RTsrc:$(SIZETO4);
|
|
shft:$(ADDRSIZE) = OFF_BASER6 & 0x3;
|
|
addr:$(ADDRSIZE) = OFF_BASER6 - shft;
|
|
valOrig:4 = *(addr) & (0xffffffff >> ((4-shft) * 8));
|
|
valStore:4 = tmpRT << (shft*8);
|
|
*(addr) = valOrig | valStore;
|
|
}
|
|
|
|
@endif
|
|
|
|
# When the analyzer finds a matching swl/swr pair, the pcode is simplified so that
|
|
# swl does all the storing while swr is a no-op
|
|
@if ENDIAN == "big"
|
|
:swl RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2A & OFF_BASE & RTsrc & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 1; globalset(inst_next, PAIR_INSTRUCTION_FLAG);] {
|
|
*[ram]:4 OFF_BASE = RTsrc:$(SIZETO4);
|
|
}
|
|
:swr RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2E & OFF_BASE & RTsrc & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 0; ]{
|
|
}
|
|
@else
|
|
:swl RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2A & OFF_BASE & RTsrc & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 1; globalset(inst_next, PAIR_INSTRUCTION_FLAG);] {
|
|
}
|
|
:swr RTsrc, OFF_BASE is $(AMODE) & REL6=0 & prime=0x2E & OFF_BASE & RTsrc & PAIR_INSTRUCTION_FLAG=1 [ PAIR_INSTRUCTION_FLAG = 0; ]{
|
|
*[ram]:4 OFF_BASE = RTsrc:$(SIZETO4);
|
|
}
|
|
@endif
|
|
|
|
# 0000 01ss sss0 1100 iiii iiii iiii iiii
|
|
:teqi RSsrc, simmed is $(AMODE) & REL6=0 & prime=1 & cond=0xC & RSsrc & simmed {
|
|
if (RSsrc != simmed) goto <done>;
|
|
trap();
|
|
<done>
|
|
}
|
|
# 0000 01ss sss0 1000 iiii iiii iiii iiii
|
|
:tgei RSsrc, simmed is $(AMODE) & REL6=0 & prime=1 & cond=8 & RSsrc & simmed {
|
|
if (RSsrc s< simmed) goto <done>;
|
|
trap();
|
|
<done>
|
|
}
|
|
# 0000 01ss sss0 1001 iiii iiii iiii iiii
|
|
:tgeiu RSsrc, simmed is $(AMODE) & REL6=0 & prime=1 & cond=9 & RSsrc & simmed {
|
|
if (RSsrc < simmed) goto <done>;
|
|
trap();
|
|
<done>
|
|
}
|
|
# 0000 01ss sss0 1010 iiii iiii iiii iiii
|
|
:tlti RSsrc, simmed is $(AMODE) & REL6=0 & prime=1 & cond=10 & RSsrc & simmed {
|
|
if (RSsrc s>= simmed) goto <done>;
|
|
trap();
|
|
<done>
|
|
}
|
|
# 0000 01ss sss0 1011 iiii iiii iiii iiii
|
|
:tltiu RSsrc, simmed is $(AMODE) & REL6=0 & prime=1 & cond=0xB & RSsrc & simmed {
|
|
if (RSsrc >= simmed) goto <done>;
|
|
trap();
|
|
<done>
|
|
}
|
|
# 0000 01ss sss0 1110 iiii iiii iiii iiii
|
|
:tnei RSsrc, simmed is $(AMODE) & REL6=0 & prime=1 & cond=0xE & RSsrc & simmed {
|
|
if (RSsrc == simmed) goto <done>;
|
|
trap();
|
|
<done>
|
|
}
|
|
|
|
############################
|
|
#
|
|
# MIPS64 Instructions to be included with all MIPS32 processors
|
|
#
|
|
############################
|
|
|
|
## Allow MIPS 64 instructions below for compilers
|
|
## using a 64-bit chip, but really keeping things to 32-bits
|
|
# 0110 00ss ssst tttt iiii iiii iiii iiii
|
|
:daddi RT, RSsrc, simmed is $(AMODE) & REL6=0 & prime=0x18 & RSsrc & RT & simmed {
|
|
RT = RSsrc + simmed;
|
|
}
|
|
|
|
####
|
|
#
|
|
# Release 6 semantics
|
|
#
|
|
####
|
|
|
|
:addiupc RSsrc, S19L2 is $(AMODE) & REL6=1 & prime=0x3B & bitz19=0 & RSsrc & S19L2 {
|
|
RSsrc = inst_start + sext(S19L2);
|
|
}
|
|
|
|
:align RD, RS32src, RT32src, bp2 is $(AMODE) & REL6=1 & prime=0x1F & spec3=0x2 & fct=0x20 & bp2 & RS32src & RT32src & RD {
|
|
tmp:4 = RT32src << (8 * bp2);
|
|
tmp = tmp | (RS32src >> (32 - (8 * bp2)));
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:aluipc RSsrc, S16L16 is $(AMODE) & REL6=1 & prime=0x3B & op=0x1F & RSsrc & S16L16 {
|
|
RSsrc = inst_start + sext(S16L16);
|
|
RSsrc = RSsrc & ~0xFFFF;
|
|
}
|
|
|
|
:aui RTsrc, RSsrc, S16L16 is $(AMODE) & REL6=1 & prime=0x0F & RSsrc & RTsrc & S16L16 {
|
|
RTsrc = RSsrc + sext(S16L16);
|
|
}
|
|
|
|
:auipc RSsrc, S16L16 is $(AMODE) & REL6=1 & prime=0x3B & op=0x1E & RSsrc & S16L16 {
|
|
RSsrc = inst_start + sext(S16L16);
|
|
}
|
|
|
|
# 0000 0100 0001 0001 iiii iiii iiii iiii
|
|
:bal Rel16 is $(AMODE) & REL6=1 & prime=0x01 & cond=0x11 & rs=0 & Rel16 {
|
|
ra = inst_next;
|
|
delayslot(1);
|
|
call Rel16;
|
|
}
|
|
|
|
:bal Rel16 is $(AMODE) & REL6=1 & prime=0x01 & cond=0x11 & rs=0 & off16=1 & Rel16 {
|
|
ra = inst_next;
|
|
delayslot(1);
|
|
goto Rel16;
|
|
}
|
|
|
|
:balc Rel26 is $(AMODE) & REL6=1 & prime=0x3A & Rel26 {
|
|
ra = inst_next;
|
|
call Rel26;
|
|
}
|
|
|
|
:bc Rel26 is $(AMODE) & REL6=1 & prime=0x32 & Rel26 {
|
|
goto Rel26;
|
|
}
|
|
|
|
:bc2eqz op, Rel16 is $(AMODE) & REL6=1 & prime=0x12 & copop=0x09 & op & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, op:1);
|
|
if (tmp == 0) goto inst_next;
|
|
goto Rel16;
|
|
}
|
|
|
|
:bc2nez op, Rel16 is $(AMODE) & REL6=1 & prime=0x12 & copop=0x0D & op & Rel16 {
|
|
tmp:1 = getCopCondition(2:1, op:1);
|
|
if (tmp != 0) goto inst_next;
|
|
goto Rel16;
|
|
}
|
|
|
|
:bad1 is $(AMODE) & REL6=1 & prime=0x06 & rs=0 & rt=0 unimpl
|
|
:blezalc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x06 & rs=0 & RTsrc & Rel16 {
|
|
if (RTsrc s> 0) goto inst_next;
|
|
ra = inst_next;
|
|
call Rel16;
|
|
}
|
|
|
|
:bgezalc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x06 & rs=rt & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc s< 0) goto inst_next;
|
|
ra = inst_next;
|
|
call Rel16;
|
|
}
|
|
|
|
:bgeuc RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x06 & rt!=0 & rs!=rt & RSsrc & RTsrc & Rel16 {
|
|
if (RSsrc >= RTsrc) goto Rel16;
|
|
}
|
|
|
|
:bad2 is $(AMODE) & REL6=1 & prime=0x07 & rs=0 & rt=0 unimpl
|
|
:bgtzalc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x07 & rs=0 & RTsrc & Rel16 {
|
|
if (RTsrc s<= 0) goto inst_next;
|
|
ra = inst_next;
|
|
call Rel16;
|
|
}
|
|
|
|
:bltzalc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x07 & rs=rt & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc s>= 0) goto inst_next;
|
|
ra = inst_next;
|
|
call Rel16;
|
|
}
|
|
|
|
:bltuc RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x07 & rt!=0 & rs!=rt & RSsrc & RTsrc & Rel16 {
|
|
if (RSsrc < RTsrc) goto Rel16;
|
|
}
|
|
|
|
|
|
:beqzalc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x08 & rs=0 & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc s> 0) goto inst_next;
|
|
ra = inst_next;
|
|
call Rel16;
|
|
}
|
|
|
|
:beqc RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x08 & rs!=0 & rs<rt & RSsrc & RTsrc & Rel16 {
|
|
if (RSsrc == RTsrc) goto Rel16;
|
|
}
|
|
|
|
:bovc RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x08 & RSsrc & RTsrc & rs32 & rt32 & Rel16 {
|
|
tmpS:8 = sext(rs32);
|
|
tmpT:8 = sext(rt32);
|
|
tmpS = tmpS + tmpT;
|
|
tmpF:1 = (tmpS s> 0x7FFFFFFF) || (tmpS s< -2147483648);
|
|
@if REGSIZE == "8"
|
|
tmpF = tmpF || (RTsrc s> 0x7FFFFFFF) || (RTsrc s< -2147483648) || (RSsrc s> 0x7FFFFFFF) || (RSsrc s< -2147483648);
|
|
@endif
|
|
if (tmpF == 1) goto Rel16;
|
|
}
|
|
|
|
:bnezalc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x18 & rs=0 & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc == 0) goto inst_next;
|
|
ra = inst_next;
|
|
call Rel16;
|
|
}
|
|
|
|
:bnec RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x18 & rs!=0 & rs<rt & RSsrc & RTsrc & Rel16 {
|
|
if (RSsrc != RTsrc) goto Rel16;
|
|
}
|
|
|
|
:bnvc RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x18 & RSsrc & RTsrc & rs32 & rt32 & Rel16 {
|
|
tmpS:8 = sext(rs32);
|
|
tmpT:8 = sext(rt32);
|
|
tmpS = tmpS + tmpT;
|
|
tmpF:1 = (tmpS s> 0x7FFFFFFF) || (tmpS s< -2147483648);
|
|
@if REGSIZE == "8"
|
|
tmpF = tmpF || (RTsrc s> 0x7FFFFFFF) || (RTsrc s< -2147483648) || (RSsrc s> 0x7FFFFFFF) || (RSsrc s< -2147483648);
|
|
@endif
|
|
if (tmpF == 0) goto Rel16;
|
|
}
|
|
|
|
:bad3 is $(AMODE) & REL6=1 & prime=0x16 & rs=0 & rt=0 unimpl
|
|
:blezc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x16 & rs=0 & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc s<= 0) goto Rel16;
|
|
}
|
|
:bgezc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x16 & rs=rt & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc s>= 0) goto Rel16;
|
|
}
|
|
:bgec RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x16 & RSsrc & RTsrc & Rel16 {
|
|
if (RSsrc s>= RTsrc) goto Rel16;
|
|
}
|
|
|
|
|
|
:bad4 is $(AMODE) & REL6=1 & prime=0x17 & rs=0 & rt=0 unimpl
|
|
:bgtzc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x17 & rs=0 & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc s> 0) goto Rel16;
|
|
}
|
|
|
|
:bltzc RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x17 & rs=rt & rt!=0 & RTsrc & Rel16 {
|
|
if (RTsrc s< 0) goto Rel16;
|
|
}
|
|
|
|
:bltc RSsrc, RTsrc, Rel16 is $(AMODE) & REL6=1 & prime=0x17 & RSsrc & RTsrc & Rel16 {
|
|
if (RSsrc s< RTsrc) goto Rel16;
|
|
}
|
|
|
|
# The jic instruction takes care of the 'bad' case here
|
|
:beqzc RSsrc, Rel21 is $(AMODE) & REL6=1 & prime=0x36 & RSsrc & Rel21 {
|
|
if (RSsrc == 0) goto Rel21;
|
|
}
|
|
|
|
# The jialc instruction takes care of the 'bad' case here
|
|
:bnezc RSsrc, Rel21 is $(AMODE) & REL6=1 & prime=0x3E & RSsrc & Rel21 {
|
|
if (RSsrc != 0) goto Rel21;
|
|
}
|
|
|
|
:bitswap RD, RT32src is $(AMODE) & REL6=1 & prime=0x1F & zero21=0 & fct2=0 & bshfl=0x20 & RT32src & RD {
|
|
tmp:4 = bitSwap(RT32src);
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:clo RD, RSsrc is $(AMODE) & REL6=1 & prime=0x00 & op=0 & sa=0x1 & fct=0x11 & RD & RSsrc {
|
|
RD = countLeadingOnes( RSsrc );
|
|
}
|
|
|
|
:clz RD, RSsrc is $(AMODE) & REL6=1 & prime=0x00 & op=0 & sa=0x1 & fct=0x10 & RD & RSsrc {
|
|
RD = countLeadingZeros( RSsrc );
|
|
}
|
|
|
|
:div RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x1A & fct2=0x02 & RD & RS32src & RT32src {
|
|
tmp:4 = RS32src s/ RT32src;
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:mod RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x1A & fct2=0x03 & RD & RS32src & RT32src {
|
|
tmp:4 = RS32src s% RT32src;
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:divu RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x1B & fct2=0x02 & RD & RS32src & RT32src {
|
|
tmp:4 = RS32src / RT32src;
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:modu RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x1B & fct2=0x03 & RD & RS32src & RT32src {
|
|
tmp:4 = RS32src % RT32src;
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:dvp RT is $(AMODE) & REL6=1 & prime=0x10 & mfmc0=0x0B & fct=0x24 & RT & RD0 & zero5=0 & zero4=0 {
|
|
disableProcessor(RT);
|
|
}
|
|
|
|
:evp RT is $(AMODE) & REL6=1 & prime=0x10 & mfmc0=0x0B & fct=0x04 & RT & RD0 & zero5=0 & zero4=0 {
|
|
enableProcessor(RT);
|
|
}
|
|
|
|
# NOTE: Unlike almost every other branch/jump that has an immediate, the immediate is *IS NOT* shifted. This allows
|
|
# this instruction to serve same function as jalx in pre-6.
|
|
:jialc RTsrc, simmed is $(AMODE) & REL6=1 & prime=0x3E & jsub=0x00 & RTsrc & simmed {
|
|
build RTsrc;
|
|
tmp:$(REGSIZE) = sext(simmed:2) + RTsrc;
|
|
JXWritePC(tmp);
|
|
ra = inst_next;
|
|
call [pc];
|
|
}
|
|
|
|
:jic RTsrc, simmed is $(AMODE) & REL6=1 & prime=0x36 & jsub=0x00 & RTsrc & simmed {
|
|
build RTsrc;
|
|
tmp:$(REGSIZE) = sext(simmed:2) + RTsrc;
|
|
JXWritePC(tmp);
|
|
call [pc];
|
|
}
|
|
|
|
@ifndef COPR_C
|
|
:ldc2 RTsrc, simmed11(baser6) is $(AMODE) & REL6=1 & prime=0x12 & copop=0x0E & simmed11 & baser6 & RTsrc {
|
|
tmp:$(REGSIZE) = simmed11;
|
|
tmp = tmp + baser6;
|
|
tmpa:$(ADDRSIZE) = 0;
|
|
ValCast(tmpa,tmp);
|
|
setCopReg(2:1, RTsrc, *[ram]:8 tmpa);
|
|
}
|
|
@endif
|
|
|
|
:ll RT, OFF_BASER6 is $(AMODE) & REL6=1 & prime=0x1F & fct=0x36 & bit6=0 & OFF_BASER6 & RT {
|
|
RT = sext(*[ram]:4 OFF_BASER6);
|
|
}
|
|
|
|
:llx RT, OFF_BASER6 is $(AMODE) & REL6=1 & prime=0x1F & fct=0x36 & bit6=1 & OFF_BASER6 & RT {
|
|
RT = sext(*[ram]:4 OFF_BASER6);
|
|
}
|
|
|
|
:llxe RT, OFF_BASER6 is $(AMODE) & REL6=1 & prime=0x1F & fct=0x27 & bit6=1 & OFF_BASER6 & RT {
|
|
RT = sext(*[ram]:4 OFF_BASER6);
|
|
}
|
|
|
|
:lsa RD, RS32src, RT32src, SAV is $(AMODE) & REL6=1 & prime=0x00 & fct=0x05 & spec3=0 & SAV & RD & RS32src & RT32src {
|
|
tmp:4 = (RS32src << SAV) + RT32src;
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
@ifndef COPR_C
|
|
:lwc2 RTsrc, simmed11(baser6) is $(AMODE) & REL6=1 & prime=0x12 & copop=0x0A & simmed11 & baser6 & RTsrc {
|
|
tmp:$(REGSIZE) = simmed11;
|
|
tmp = tmp + baser6;
|
|
tmpa:$(ADDRSIZE) = 0;
|
|
ValCast(tmpa,tmp);
|
|
setCopReg( 2:1, RTsrc, *[ram]:4 tmpa);
|
|
}
|
|
@endif
|
|
|
|
:lwpc RS, S19L2 is $(AMODE) & REL6=1 & prime=0x3B & pcrel=0x1 & RS & S19L2 {
|
|
tmp:$(REGSIZE) = inst_start + sext(S19L2);
|
|
tmpa:$(ADDRSIZE) = 0;
|
|
ValCast(tmpa,tmp);
|
|
RS = sext(*[ram]:4 tmpa);
|
|
}
|
|
|
|
:mul RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x18 & fct2=0x02 & RD & RS32src & RT32src {
|
|
tmpS:8 = sext(RS32src);
|
|
tmpT:8 = sext(RT32src);
|
|
tmpS = tmpS * tmpT;
|
|
tmp:4 = tmpS[0,32];
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:muh RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x18 & fct2=0x03 & RD & RS32src & RT32src {
|
|
tmpS:8 = sext(RS32src);
|
|
tmpT:8 = sext(RT32src);
|
|
tmpS = tmpS * tmpT;
|
|
tmp:4 = tmpS[32,32];
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:mulu RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x19 & fct2=0x02 & RD & RS32src & RT32src {
|
|
tmpS:8 = zext(RS32src);
|
|
tmpT:8 = zext(RT32src);
|
|
tmpS = tmpS * tmpT;
|
|
tmp:4 = tmpS[0,32];
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:muhu RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x19 & fct2=0x03 & RD & RS32src & RT32src {
|
|
tmpS:8 = zext(RS32src);
|
|
tmpT:8 = zext(RT32src);
|
|
tmpS = tmpS * tmpT;
|
|
tmp:4 = tmpS[32,32];
|
|
RD = sext(tmp);
|
|
}
|
|
|
|
:scx RTsrc, OFF_BASER6 is $(AMODE) & REL6=1 & prime=0x1F & fct=0x26 & bit6=1 & OFF_BASER6 & RTsrc {
|
|
*[ram]:4 OFF_BASER6 = RTsrc:$(SIZETO4);
|
|
}
|
|
|
|
:scxe RTsrc, OFF_BASER6 is $(AMODE) & REL6=1 & prime=0x1F & fct=0x1E & bit6=1 & OFF_BASER6 & RTsrc {
|
|
*[ram]:4 OFF_BASER6 = RTsrc:$(SIZETO4);
|
|
RTsrc = 1;
|
|
}
|
|
|
|
:seleqz RD, RSsrc, RTsrc is $(AMODE) & REL6=1 & prime=0x00 & fct=0x35 & fct2=0x00 & RD & RSsrc & RTsrc {
|
|
# We use tmp to cover case where rs and rd are the same reg
|
|
tmps:$(REGSIZE) = RSsrc;
|
|
tmpt:$(REGSIZE) = RTsrc;
|
|
RD = 0;
|
|
if (tmpt != 0) goto <done>;
|
|
RD = tmps;
|
|
<done>
|
|
}
|
|
|
|
:selnez RD, RSsrc, RTsrc is $(AMODE) & REL6=1 & prime=0x00 & fct=0x37 & fct2=0x00 & RD & RSsrc & RTsrc {
|
|
# We use tmp to cover case where rs and rd are the same reg
|
|
tmps:$(REGSIZE) = RSsrc;
|
|
tmpt:$(REGSIZE) = RTsrc;
|
|
RD = 0;
|
|
if (tmpt == 0) goto <done>;
|
|
RD = tmps;
|
|
<done>
|
|
}
|
|
|
|
:sigrie immed is $(AMODE) & REL6=1 & prime=0x01 & zero21=0 & cond=0x17 & immed {
|
|
signalReservedInstruction(immed:2);
|
|
}
|
|
|
|
|
|
@include "mipsfloat.sinc"
|