Files
ghidra-xtensa/data/languages/xtensaInstructions.sinc
2020-12-04 17:32:07 +01:00

1338 lines
38 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ABS - Absolute Value (RRR), pg. 246.
:abs ar, at is op2 = 0b0110 & op1 = 0 & ar & as = 0b0001 & at & op0 = 0 {
ar = at;
if (ar s> 0)
goto inst_next;
ar = -ar;
}
# ABS.S - Absolute Single Value (RRR), pg. 247.
:abs.s fr, fs is op2 = 0b1111 & op1 = 0b1010 & fr & fs & at = 0b0001 & op0 = 0b0000 {
fr = abs(fs);
}
# ADD - Add (RRR), pg. 248.
:add ar, as, at is op2 = 0b1000 & op1 = 0 & ar & as & at & op0 = 0 {
ar = as + at;
}
# ADD.N - Narrow Add (RRRN), pg. 249.
:add.n n_ar, n_as, n_at is n_ar & n_as & n_at & n_op0 = 0b1010 {
n_ar = n_as + n_at;
}
# ADD.S - Add Single (RRR), pg. 250.
:add.s fr, fs, ft is op2 = 0 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
fr = fs f+ ft;
}
# ADDI - Add Immediate (RRI8), pg. 251.
:addi at, as, s8_16.23 is s8_16.23 & ar = 0b1100 & as & at & op0 = 0b0010 {
at = as + sext(s8_16.23:1);
}
# ADDI.N - Narrow Add Immediate (RRRN), pg. 252.
:addi.n n_ar, n_as, n_s4_4.7_nozero is n_ar & n_as & n_s4_4.7_nozero & n_op0 = 0b1011 {
n_ar = n_as + n_s4_4.7_nozero;
}
# ADDMI - Add Immediate with Shift by 8, pg. 253.
:addmi at, as, s16_16.23_sb8 is s16_16.23_sb8 & ar = 0b1101 & as & at & op0 = 0b0010 {
at = as + sext(s16_16.23_sb8);
}
# ADDX2 - Add with Shift by 1, pg. 254.
:addx2 ar, as, at is op2 = 0b1001 & op1 = 0 & ar & as & at & op0 = 0 {
ar = (as << 1) + at;
}
# ADDX4 - Add with Shift by 2, pg. 255.
:addx4 ar, as, at is op2 = 0b1010 & op1 = 0 & ar & as & at & op0 = 0 {
ar = (as << 2) + at;
}
# ADDX8 - Add with Shift by 4, pg. 256.
:addx8 ar, as, at is op2 = 0b1011 & op1 = 0 & ar & as & at & op0 = 0 {
ar = (as << 3) + at;
}
# ALL4 - All 4 Booleans True, pg. 257.
:all4 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1001 & bs & bt & op0 = 0 {
local b = *[register]:1 &:4 bs+1;
local c = *[register]:1 &:4 bs+2;
local d = *[register]:1 &:4 bs+3;
bt = bs && b && c && d;
}
# ALL8 - All 8 Booleans True, pg. 258.
:all8 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1011 & bs & bt & op0 = 0 {
local b = *[register]:1 &:4 bs+1;
local c = *[register]:1 &:4 bs+2;
local d = *[register]:1 &:4 bs+3;
local e = *[register]:1 &:4 bs+4;
local f = *[register]:1 &:4 bs+5;
local g = *[register]:1 &:4 bs+6;
local h = *[register]:1 &:4 bs+7;
bt = bs && b && c && d && e && f && g && h;
}
# AND - Bitwise Logical And, pg. 259.
:and ar, as, at is op2 = 0b0001 & op1 = 0 & ar & as & at & op0 = 0 {
ar = as & at;
}
# ANDB - Boolean And, pg. 260.
:andb br, bs, bt is op2 = 0 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
br = bs && bt;
}
# ANDBC - Boolean And with Complement, pg. 261.
:andbc br, bs, bt is op2 = 0b0001 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
br = bs && !bt;
}
# ANY4 - Any 4 Booleans True, pg. 262.
:any4 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1000 & bs & bt & op0 = 0 {
local b = *[register]:1 &:4 bs+1;
local c = *[register]:1 &:4 bs+2;
local d = *[register]:1 &:4 bs+3;
bt = bs || b || c || d;
}
# ANY8 - Any 8 Booleans True, pg. 263.
:any8 bt, bs is op2 = 0 & op1 = 0 & ar = 0b1010 & bs & bt & op0 = 0 {
local b = *[register]:1 &:4 bs+1;
local c = *[register]:1 &:4 bs+2;
local d = *[register]:1 &:4 bs+3;
local e = *[register]:1 &:4 bs+4;
local f = *[register]:1 &:4 bs+5;
local g = *[register]:1 &:4 bs+6;
local h = *[register]:1 &:4 bs+7;
bt = bs || b || c || d || e || f || g || h;
}
# BALL - Branch if All Bits Set, pg. 264.
:ball srel_16.23, as, at is srel_16.23 & ar = 0b0100 & as & at & op0 = 0b0111 {
if ((~as & at) == 0)
goto srel_16.23;
}
# BANY - Branch if Any Bit Set, pg. 265.
:bany srel_16.23, as, at, is srel_16.23 & ar = 0b1000 & as & at & op0 = 0b0111 {
if ((as & at) != 0)
goto srel_16.23;
}
macro extract_bit(val, bit, result) {
result = (val >> bit)&1;
}
# BBC - Branch if Bit Clear, pg. 266.
:bbc as, at, srel_16.23 is srel_16.23 & ar = 0b0101 & as & at & op0 = 0b0111 {
local bval;
extract_bit(as, at[0,5], bval);
if (bval == 0)
goto srel_16.23;
}
# BBCI - Branch if Bit Clear immediate, pg. 267
:bbci as, u5_4.7_12, srel_16.23 is srel_16.23 & u3_13.15 = 0b011 & as & u5_4.7_12 & op0 = 0b0111 {
local bval;
extract_bit(as, u5_4.7_12, bval);
if (bval == 0)
goto srel_16.23;
}
# BBS - Branch if Bit Set, pg. 269.
:bbs as, at, srel_16.23 is srel_16.23 & ar = 0b1101 & as & at & op0 = 0b0111 {
local bval;
extract_bit(as, at[0,5], bval);
if (bval != 0)
goto srel_16.23;
}
# BBSI - Branch if Bit Set immediate, pg. 270.
:bbsi as, u5_4.7_12, srel_16.23 is srel_16.23 & u3_13.15 = 0b111 & as & u5_4.7_12 & op0 = 0b0111 {
local bval;
extract_bit(as, u5_4.7_12, bval);
if (bval != 0)
goto srel_16.23;
}
# BEQ - Branch if Equal, pg. 272.
:beq as, at, srel_16.23 is srel_16.23 & ar = 0b0001 & as & at & op0 = 0b0111 {
if (as == at)
goto srel_16.23;
}
# BEQI - Branch if Equal Immediate, pg. 273.
:beqi as, r_b4const, srel_16.23 is srel_16.23 & r_b4const & as & u2_6.7 = 0 & u2_4.5 = 0b10 & op0 = 0b0110 {
if (as == r_b4const)
goto srel_16.23;
}
# BEQZ - Branch if Equal Zero, pg. 274.
:beqz as, srel_12.23 is srel_12.23 & as & u2_6.7 = 0 & u2_4.5 = 0b01 & op0 = 0b0110 {
if (as == 0)
goto srel_12.23;
}
# BEQZ.N - Narrow Branch if Equal Zero, pg. 275.
:beqz.n n_as, urel_12.15_4.5 is urel_12.15_4.5 & n_as & n_u2_6.7 = 0b10 & n_op0 = 0b1100 {
if (n_as == 0)
goto urel_12.15_4.5;
}
# BF - Branch if False, pg. 276.
:bf bs, srel_16.23 is srel_16.23 & ar = 0 & bs & at = 0b0111 & op0 = 0b0110 {
if (!bs)
goto srel_16.23;
}
# BGE - Branch if Greater Than or Equal, pg. 277.
:bge as, at, srel_16.23 is srel_16.23 & ar = 0b1010 & as & at & op0 = 0b0111 {
if (as s>= at)
goto srel_16.23;
}
# BGEI - Branch if Greater Than or Equal Immediate, pg. 278.
:bgei as, r_b4const, srel_16.23 is srel_16.23 & r_b4const & as & u2_6.7 = 0b11 & u2_4.5 = 0b10 & op0 = 0b0110 {
if (as s>= r_b4const)
goto srel_16.23;
}
# BGEU - Branch if Greater Than or Equal Unsigned, pg. 279.
:bgeu as, at, srel_16.23 is srel_16.23 & ar = 0b1011 & as & at & op0 = 0b0111 {
if (as >= at)
goto srel_16.23;
}
# BGEUI - Branch if Greater Than or Equal Unsigned Immediate, pg. 280.
:bgeui as, r_b4constu, srel_16.23 is srel_16.23 & r_b4constu & as & u2_6.7 = 0b11 & u2_4.5 = 0b11 & op0 = 0b0110 {
if (as >= r_b4constu)
goto srel_16.23;
}
# BGEZ - Branch if Greater Than or Equal Zero, pg. 281.
:bgez as, srel_12.23 is srel_12.23 & as & u2_6.7 = 0b11 & u2_4.5 = 0b01 & op0 = 0b0110 {
if (as s>= 0)
goto srel_12.23;
}
# BLT - Branch if Less Than, pg. 282.
:blt as, at, srel_16.23 is srel_16.23 & ar = 0b0010 & as & at & op0 = 0b0111 {
if (as s< at)
goto srel_16.23;
}
# BLTI - Branch if Less Than Immediate, pg. 283.
:blti as, r_b4const, srel_16.23 is srel_16.23 & r_b4const & as & u2_6.7 = 0b10 & u2_4.5 = 0b10 & op0 = 0b0110 {
if (as s< r_b4const)
goto srel_16.23;
}
# BLTU - Branch if Less Than Unsigned, pg. 284.
:bltu as, at, srel_16.23 is srel_16.23 & ar = 0b0011 & as & at & op0 = 0b0111 {
if (as < at)
goto srel_16.23;
}
# BLTUI - Branch if Less Than Unsigned Immediate, pg. 285.
:bltui as, r_b4constu, srel_16.23 is srel_16.23 & r_b4constu & as & u2_6.7 = 0b10 & u2_4.5 = 0b11 & op0 = 0b0110 {
if (as < r_b4constu)
goto srel_16.23;
}
# BLTZ - Branch if Less Than Zero, pg. 286.
:bltz as, srel_12.23 is srel_12.23 & as & u2_6.7 = 0b10 & u2_4.5 = 0b01 & op0 = 0b0110 {
if (as s< 0)
goto srel_12.23;
}
# BNALL - Branch if Not-All Bits Set, pg. 287.
:bnall srel_16.23, as, at is srel_16.23 & ar = 0b1100 & as & at & op0 = 0b0111 {
if ((~as & at) != 0)
goto srel_16.23;
}
# BNE - Branch if Not Equal, pg. 288.
:bne as, at, srel_16.23 is srel_16.23 & ar = 0b1001 & as & at & op0 = 0b0111 {
if (as != at)
goto srel_16.23;
}
# BNEI - Branch if Not EquaL Immediate, pg. 289.
:bnei as, r_b4const, srel_16.23 is srel_16.23 & r_b4const & as & u2_6.7 = 0b01 & u2_4.5 = 0b10 & op0 = 0b0110 {
if (as != r_b4const)
goto srel_16.23;
}
# BNEZ - Branch if Not Equal Zero, pg. 290.
:bnez as, srel_12.23 is srel_12.23 & as & u2_6.7 = 0b01 & u2_4.5 = 0b01 & op0 = 0b0110 {
if (as != 0)
goto srel_12.23;
}
# BNEZ.N - Narrow Branch if Not Equal Zero, pg. 291.
:bnez.n n_as, urel_12.15_4.5 is urel_12.15_4.5 & n_as & n_u2_6.7 = 0b11 & n_op0 = 0b1100 {
if (n_as != 0)
goto urel_12.15_4.5;
}
# BNONE - Branch if No Bit Set, pg. 292.
:bnone srel_16.23, as, at, is srel_16.23 & ar = 0 & as & at & op0 = 0b0111 {
if ((as & at) == 0)
goto srel_16.23;
}
# BREAK - Breakpoint, pg. 293.
:break u4_8.11, u4_4.7 is op2 = 0 & op1 = 0 & ar = 0b0100 & u4_8.11 & u4_4.7 & op0 = 0 {
breakpoint(0x001000:4, u4_8.11:1, u4_4.7:1);
}
# BREAK.N - Narrow Breakpoint, pg. 295.
:break.n n_u4_8.11 is n_ar = 0b1111 & n_u4_8.11 & n_at = 0b0010 & n_op0 = 0b1101 {
breakpoint(0x010000:4, n_u4_8.11:1, 0:1);
}
# BT - Branch if True, pg. 296.
:bt bs, srel_16.23 is srel_16.23 & ar = 0b0001 & bs & at = 0b0111 & op0 = 0b0110 {
if (bs)
goto srel_16.23;
}
# CALL0 - Non-windowed Call, pg. 297.
:call0 srel_6.23_sb2 is srel_6.23_sb2 & u2_4.5 = 0 & op0 = 0b0101 {
#local dst = srel_6.23_sb2;
i2 = a2;
i3 = a3;
i4 = a4;
i5 = a5;
i6 = a6;
i7 = a7;
a0 = inst_start + 3;
call srel_6.23_sb2;
}
# CALLX0 - Non-windowed Call Register, pg. 304.
:callx0 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b11 & u2_4.5 = 0 & op0 = 0 {
local dst = as;
i2 = a2;
i3 = a3;
i4 = a4;
i5 = a5;
i6 = a6;
i7 = a7;
a0 = inst_start + 3;
call [dst];
}
# CEIL.S - Ceiling Single to Fixed, pg. 311.
:ceil.s ar, fs, u4_4.7 is op2 = 0b1011 & op1 = 0b1010 & ar & fs & u4_4.7 & op0 = 0 {
local scale:4 = int2float(1:1 << u4_4.7:1);
ar = ceil(fs f* scale);
}
# CLAMPS - Signed Clamp, pg. 312.
:clamps ar, as, u5_4.7_plus7 is op2 = 0b0011 & op1 = 0b0011 & ar & as & u5_4.7_plus7 & op0 = 0 {
# ar ← min(max(as, -2^{u5_4.7_plus7}), 2^{u5_4.7_plus7}-1)
local maxval:4 = (1 << u5_4.7_plus7) - 1;
local minval:4 = -(1 << u5_4.7_plus7);
if (as s< minval)
goto <write_minval>;
if (as s> maxval)
goto <write_maxval>;
ar = as;
goto inst_next;
<write_minval>
ar = minval;
goto inst_next;
<write_maxval>
ar = maxval;
# fallthrough inst_next
}
# DHI - Data Cache Hit Invalidate, pg. 313.
:dhi as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b0110 & op0 = 0b0010 {
dhi(as + zext(u10_16.23_sb2));
}
# DHU - Data Cache Hit Unlock, pg. 315.
:dhu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0010 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
dhu(as + zext(u8_20.23_sb4));
}
# DHWB - Data Cache Hit Writeback, pg. 317.
:dhwb as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b0100 & op0 = 0b0010 {
dhwb(as + zext(u10_16.23_sb2));
}
# DHWBI - Data Cache Hit Writeback Invalidate, pg. 319.
:dhwbi as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b0101 & op0 = 0b0010 {
dhwbi(as + zext(u10_16.23_sb2));
}
# DII - Data Cache Index Invalidate, pg. 321.
:dii as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b0111 & op0 = 0b0010 {
dii(as + zext(u10_16.23_sb2));
}
# DIU - Data Cache Index Unlock, pg. 323.
:diu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0011 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
diu(as + zext(u8_20.23_sb4));
}
# DIWB - Data Cache Index Write Back, pg. 325.
:diwb as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0100 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
diwb(as + zext(u8_20.23_sb4));
}
# DIWBI - Data Cache Index Write Back Invalidate, pg. 327.
:diwbi as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0101 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
diwbi(as + zext(u8_20.23_sb4));
}
# DPFL - Data Cache Prefetch and Lock, pg. 329.
:dpfl as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0 & ar = 0b0111 & as & at = 0b1000 & op0 = 0b0010 {
dpfl(as + zext(u8_20.23_sb4));
}
# DPFR - Data Cache Prefetch for Read, pg. 331.
:dpfr as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0 & op0 = 0b0010 {
dpfr(as + zext(u10_16.23_sb2));
}
# DPFRO - Data Cache Prefetch for Read Once, pg. 333.
:dpfro as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b0010 & op0 = 0b0010 {
dpfro(as + zext(u10_16.23_sb2));
}
# DPFW - Data Cache Prefetch for Write, pg. 335.
:dpfw as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b0001 & op0 = 0b0010 {
dpfw(as + zext(u10_16.23_sb2));
}
# DPFWO - Data Cache Prefetch for Write Once, pg. 337.
:dpfwo as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b0011 & op0 = 0b0010 {
dpfwo(as + zext(u10_16.23_sb2));
}
# DSYNC - Load/Store Synchronize, pg. 339.
:dsync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b0011 & op0 = 0 {
dsync();
}
# ESYNC - Execute Synchronize, pg. 342.
:esync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b0010 & op0 = 0 {
esync();
}
# EXCW - Exception Wait, pg. 343.
:excw is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b1000 & op0 = 0 {
excw();
}
# EXTUI - Extract Unsigned Immediate, pg. 344.
:extui ar, at, u5_8.11_16, u5_20.23_plus1 is u5_20.23_plus1 & u3_17.19 = 0b010 & u5_8.11_16 & ar & at & op0 = 0 {
local shifted:4 = at >> u5_8.11_16;
local mask:4 = (1:4 << (u5_20.23_plus1))-1;
ar = shifted & mask;
}
# EXTW - External Wait, pg. 345.
:extw is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b1101 & op0 = 0 {
extw();
}
# FLOAT.S - Convert Fixed to Single, pg. 346.
:float.s fr, as, u4_4.7 is op2 = 0b1100 & op1 = 0b1010 & fr & as & u4_4.7 & op0 = 0 {
local f = int2float(as);
local d = int2float(1:2 << u4_4.7:2);
fr = d f/ f;
}
# FLOOR.S - Floor Single to Fixed, pg. 347.
:floor.s ar, fs, u4_4.7 is op2 = 0b1010 & op1 = 0b1010 & ar & fs & u4_4.7 & op0 = 0 {
local scale:4 = int2float(1:2 << u4_4.7:2);
ar = floor(fs f* scale);
}
# IDTLB - Invalidate Data TLB Entry, pg. 348.
:idtlb as is op2 = 0b0101 & op1 = 0 & ar = 0b1100 & as & at = 0 & op0 = 0 {
idtlb();
}
# IHI - Instruction Cache Hit Invalidate, pg. 349.
:ihi as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b1110 & op0 = 0b0010 {
ihi(as + zext(u10_16.23_sb2));
}
# IHU - Instruction Cache Hit Unlock, pg. 351.
:ihu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0010 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
ihu(as + zext(u8_20.23_sb4));
}
# III - Instruction Cache Index Invalidate, pg. 353.
:iii as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b1111 & op0 = 0b0010 {
iii(as + zext(u10_16.23_sb2));
}
# IITLB - Invalidate Instruction TLB Entry, pg. 355.
:iitlb as is op2 = 0b0101 & op1 = 0 & ar = 0b0100 & as & at = 0 & op0 = 0 {
iitlb(as);
}
# IIU - Instruction Cache Index Unlock, pg. 356.
:iiu as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0b0011 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
iiu(as + zext(u8_20.23_sb4));
}
# ILL - Illegal Instruction, pg. 358.
:ill is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & at = 0 & op0 = 0 {
ill();
goto inst_start;
}
# ILL.N - Narrow Illegal Instruction, pg. 359.
:ill.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0110 & n_op0 = 0b1101 {
ill();
goto inst_start;
}
# IPF - Instruction Cache Prefetch, pg. 360.
:ipf as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0111 & as & at = 0b1100 & op0 = 0b0010 {
ipf(as + zext(u10_16.23_sb2));
}
# IPFL - Instruction Cache Prefetch and Lock, pg. 362.
:ipfl as, u8_20.23_sb4 is u8_20.23_sb4 & op1 = 0 & ar = 0b0111 & as & at = 0b1101 & op0 = 0b0010 {
ipfl(as + zext(u8_20.23_sb4));
}
# ISYNC - Instruction Fetch Synchronize, pg. 364.
:isync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0 & op0 = 0 {
isync();
}
# J - Unconditional Jump, pg. 366.
:j srel_6.23 is srel_6.23 & u2_4.5 = 0 & op0 = 0b0110 {
goto srel_6.23;
}
# J.L is a macro.
# RET (JX A0) - Non-Windowed Return, pg. 478.
:ret is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & u2_6.7 = 0b10 & u2_4.5 = 0b10 & op0 = 0 {
return [a0];
}
# The manual suggests that RET is equivalent to JX A0, yet RET has bit 5 unset, JX doesnt.
:ret is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & u2_6.7 = 0b10 & u2_4.5 = 0b00 & op0 = 0 {
return [a0];
}
# JX - Uncoditional Jump Register, pg. 368.
:jx as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b10 & u2_4.5 = 0b10 & op0 = 0 {
goto [as];
}
# L8UI - Load 8-bit Unsigned, pg. 369.
:l8ui at, as, u8_16.23 is u8_16.23 & ar = 0 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u8_16.23:1);
at = zext(*:1 addr);
}
# L16SI - Load 16-bit Signed, pg. 370.
:l16si at, as, u9_16.23_sb1 is u9_16.23_sb1 & ar = 0b1001 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u9_16.23_sb1);
at = sext(*:2 addr);
}
# L16UI - Load 16-bit Unsigned, pg. 372.
:l16ui at, as, u9_16.23_sb1 is u9_16.23_sb1 & ar = 0b001 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u9_16.23_sb1);
at = zext(*:2 addr);
}
# L32AI - Load 32-bit Acquire, pg. 374.
:l32ai at, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b1011 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u10_16.23_sb2);
at = *:4 addr;
acquire(addr);
}
# L32I - Load 32-bit, pg. 378.
:l32i at, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0010 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u10_16.23_sb2);
at = *:4 addr;
}
# L32I.N - Narrow Load 32-bit, pg. 380.
:l32i.n n_at, n_as, n_u6_12.15_sb2 is n_u6_12.15_sb2 & n_as & n_at & n_op0 = 0b1000 {
local addr:4 = n_as + zext(n_u6_12.15_sb2);
n_at = *:4 addr;
}
# L32R - Load 32-bit PC-relative, pg. 382.
:l32r at, srel_8.23_oex_sb2 is srel_8.23_oex_sb2 & at & op0 = 0b0001 {
at = srel_8.23_oex_sb2;
}
# LDCT - Load Data Cache Tag, pg. 384.
:ldct at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b1000 & as & at & op0 = 0 {
at = ldct(as);
}
# LICT - Load Instruction Cache Tag, pg. 388.
:lict at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0 & as & at & op0 = 0 {
at = lict(as);
}
# LICW - Load Instruction Cache Word, pg. 390.
:licw at, as is op2 = 0b1111 & op1 = 0b0010 & ar = 0 & as & at & op0 = 0 {
at = licw(as);
}
# LSI - Load Single Immediate, pg. 398.
:lsi ft, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0 & as & ft & op0 = 0b0011 {
local addr:4 = as + zext(u10_16.23_sb2);
ft = *:4 addr;
}
# LSIU - Load Single Immediate with Update, pg. 400.
:lsiu ft, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b1000 & as & ft & op0 = 0b0011 {
local addr:4 = as + zext(u10_16.23_sb2);
ft = *:4 addr;
as = addr;
}
# LSX - Load Single Indexed, pg. 402.
:lsx fr, as, at is op2 = 0 & op1 = 0b1000 & fr & as & at & op0 = 0 {
local addr:4 = as+at;
fr = *:4 addr;
}
# LSXU - Load Single Indexed with Update, pg. 404.
:lsxu fr, as, at is op2 = 0b0001 & op1 = 0b1000 & fr & as & at & op0 = 0 {
local addr:4 = as+at;
fr = *:4 addr;
as = addr;
}
# MADD.S - Multiply and Add Single, pg. 406.
:madd.s fr, fs, ft is op2 = 0b0100 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
fr = fr f+ (fs f* ft);
}
# MAX - Maximum Value, pg. 407.
:max ar, as, at is op2 = 0b0101 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (as s> at)
goto <s_larger>;
ar = at;
goto inst_next;
<s_larger>
ar = as;
}
# MAXU - Maximum Value Unsigned, pg. 408.
:maxu ar, as, at is op2 = 0b0111 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (as > at)
goto <s_larger>;
ar = at;
goto inst_next;
<s_larger>
ar = as;
}
# MEMW - Memory Wait, pg. 409.
:memw is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b1100 & op0 = 0 {
memw();
}
# MIN - Minimum Value, pg. 410.
:min ar, as, at is op2 = 0b0100 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (as s< at)
goto <s_smaller>;
ar = at;
goto inst_next;
<s_smaller>
ar = as;
}
# MINU - Minimum Value Unsigned, pg. 411.
:minu ar, as, at is op2 = 0b0110 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (as < at)
goto <s_smaller>;
ar = at;
goto inst_next;
<s_smaller>
ar = as;
}
# MOV.N - Narrow Move, pg. 413.
:mov.n n_at, n_as is n_ar = 0 & n_as & n_at & n_op0 = 0b1101 {
n_at = n_as;
}
# MOV.S - Move Single, pg. 414.
:mov.s fr, fs is op2 = 0b1111 & op1 = 0b1010 & fr & fs & at = 0 & op0 = 0 {
fr = fs;
}
# MOVEQZ - Move if Equal to Zero, pg. 415.
:moveqz ar, as, at is op2 = 0b1000 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (at != 0)
goto inst_next;
ar = as;
}
# MOVEQZ.S - Move Single if Equal to Zero, pg. 416.
:moveqz.s fr, fs, at is op2 = 0b1000 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
if (at != 0)
goto inst_next;
fr = fs;
}
# MOVF - Move if False, pg. 417.
:movf ar, as, bt is op2 = 0b1100 & op1 = 0b0011 & ar & as & bt & op0 = 0 {
if (bt)
goto inst_next;
ar = as;
}
# MOVF.S - Move Single if False, pg. 418.
:movf.s fr, fs, bt is op2 = 0b1100 & op1 = 0b1011 & fr & fs & bt & op0 = 0 {
if (bt)
goto inst_next;
fr = fs;
}
# MOVGEZ - Move if Greater Than or Equal to Zero, pg. 419.
:movgez ar, as, at is op2 = 0b1011 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (at s< 0)
goto inst_next;
ar = as;
}
# MOVGEZ.S - Move Single if Greater Than or Equal to Zero, pg. 420.
:movgez.s fr, fs, at is op2 = 0b1011 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
if (at s< 0)
goto inst_next;
fr = fs;
}
# MOVI - Move Immediate, pg. 421.
:movi at, s16_16.23_8.11 is s16_16.23_8.11 & ar = 0b1010 & at & op0 = 0b0010 {
local val:4 = sext(s16_16.23_8.11);
at = val;
}
# MOVI.N - Narrow Move Immediate, pg. 422.
:movi.n n_as, n_s8_12.15_4.6_asymm is n_s8_12.15_4.6_asymm & n_as & n_u1_7 = 0 & n_op0 = 0b1100 {
local val:4 = sext(n_s8_12.15_4.6_asymm);
n_as = val;
}
# MOVLTZ - Move if Less Than Zero, pg. 423.
:movltz ar, as, at is op2 = 0b1010 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (at s>= 0)
goto inst_next;
ar = as;
}
# MOVLTZ.S - Move Single if Less Than Zero, pg. 424.
:movltz.s fr, fs, at is op2 = 0b1010 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
if (at s>= 0)
goto inst_next;
fr = fs;
}
# MOVNEZ - Move if Not Equal to Zero, pg. 425.
:movnez ar, as, at is op2 = 0b1001 & op1 = 0b0011 & ar & as & at & op0 = 0 {
if (at == 0)
goto inst_next;
ar = as;
}
# MOVNEZ.S - Move Single if Not Equal to Zero, pg. 426.
:movnez.s fr, fs, at is op2 = 0b1001 & op1 = 0b1011 & fr & fs & at & op0 = 0 {
if (at == 0)
goto inst_next;
fr = fs;
}
# MOVT - Move if True, pg. 428.
:movt ar, as, bt is op2 = 0b1101 & op1 = 0b0011 & ar & as & bt & op0 = 0 {
if (!bt)
goto inst_next;
ar = as;
}
# MOVT.S - Move Single if True, pg. 429.
:movt.s fr, fs, bt is op2 = 0b1101 & op1 = 0b1011 & fr & fs & bt & op0 = 0 {
if (!bt)
goto inst_next;
fr = fs;
}
# MSUB.S - Multiply and Subtract Single, pg. 430.
:msub.s fr, fs, ft is op2 = 0b0101 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
fr = fr f- (fs f* ft);
}
# MUL.S - Multiply Single, pg. 435.
:mul.s fr, fs, ft is op2 = 0b0010 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
fr = fs f* ft;
}
# MUL16S - Multiply 16-bit Signed, pg. 436.
:mul16s ar, as, at is op2 = 0b1101 & op1 = 0b0001 & ar & as & at & op0 = 0 {
ar = sext(as:2) * sext(at:2);
}
# MUL16U - Multiply 16-bit Unsigned, pg. 437.
:mul16u ar, as, at is op2 = 0b1100 & op1 = 0b0001 & ar & as & at & op0 = 0 {
ar = zext(as:2) * zext(at:2);
}
# MULL - Multiply Low, pg. 450.
:mull ar, as, at is op2 = 0b1000 & op1 = 0b0010 & ar & as & at & op0 = 0 {
ar = as * at;
}
# MULSH - Multiply Signed High, pg. 455.
:mulsh ar, as, at is op2 = 0b1011 & op1 = 0b0010 & ar & as & at & op0 = 0 {
local s64:8 = sext(as);
local t64:8 = sext(at);
local p:8 = (s64 * t64);
ar = p(4);
}
# MULUH - Multiply Unsigned High, pg. 456.
:muluh ar, as, at is op2 = 0b1010 & op1 = 0b0010 & ar & as & at & op0 = 0 {
local s64:8 = zext(as);
local t64:8 = zext(at);
local p:8 = (s64 * t64);
ar = p(4);
}
# NEG - Negate, pg. 457.
:neg ar, at is op2 = 0b0110 & op1 = 0 & ar & as = 0 & at & op0 = 0 {
ar = -at;
}
# NEG.S - Negate Single, pg. 458.
:neg.s fr, fs is op2 = 0b1111 & op1 = 0b1010 & fr & fs & at = 0b0110 & op0 = 0 {
fr = f- fs;
}
# NOP - No Operation, pg. 459.
:nop is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b1111 & op0 = 0 { }
# NOP.N - Narrow No Operation, pg. 460.
:nop.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0011 & n_op0 = 0b1101 { }
# NSA - Normalization Shift Amount, pg. 461.
:nsa at, as is op2 = 0b0100 & op1 = 0 & ar = 0b1110 & as & at & op0 = 0 {
# https://stackoverflow.com/questions/54772520/normalizing-a-two-complement-number
at = nsa(as);
}
# NSAU - Normalization Shift Amount Unsigned, pg. 462. (Count leading zeros)
:nsau at, as is op2 = 0b0100 & op1 = 0 & ar = 0b1111 & as & at & op0 = 0 {
local z4 = as[16,16] == 0;
local t3 = zext(z4)*as[0,16] + zext(!z4)*as[16,16];
local z3 = t3[8,8] == 0;
local t2 = (z3)*t3[0,8] + (!z3)*t3[8,8];
local z2 = t2[4,4] == 0;
local t1 = (z2)*t2[0,4] + (!z2)*t2[4,4];
local z1 = t1[2,2] == 0;
local z0 = (z1)*(t1[1,1] == 0) + (!z1)*(t1[3,1] == 0);
local all0 = as == 0;
at = zext((all0)*32 + (!all0)*(z4<<4 | z3<<3 | z2<<2 | z1<<1 | z0));
}
# OEQ.S - Compare Single Equal, pg. 463.
:oeq.s br, fs, ft is op2 = 0b0010 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
br = !nan(fs) && !nan(ft) && fs f== ft;
}
# OLE.S - Compare Single Ordered and Less Than or Equal, pg. 464
:ole.s br, fs, ft is op2 = 0b0110 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
br = !nan(fs) && !nan(ft) && fs f<= ft;
}
# OLT.S - Compare Single Ordered and Less Than, pg. 465.
:olt.s br, fs, ft is op2 = 0b0100 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
br = !nan(fs) && !nan(ft) && fs f< ft;
}
# MOV - Move, pg. 412. Special case of OR as, at, at.
:mov ar, as is op2 = 0b0010 & op1 = 0 & ar & as & as = at & op0 = 0 {
ar = as;
}
# OR - Bitwise Logical Or, pg. 466.
:or ar, as, at is op2 = 0b0010 & op1 = 0 & ar & as & at & op0 = 0 {
ar = as | at;
}
# ORB - Boolean Or, pg. 467.
:orb br, bs, bt is op2 = 0b0010 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
br = bs || bt;
}
# ORBC - Boolean Or with Complement, pg. 468.
:orbc br, bs, bt is op2 = 0b0011 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
br = bs || !bt;
}
# PDTLB - Probe Data TLB, pg. 469.
:pdtlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1101 & as & at & op0 = 0 {
at = pdtlb(as);
}
# PITLB - Probe Instruction TLB, pg. 470.
:pitlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0101 & as & at & op0 = 0 {
at = pitlb(as);
}
# QUOS - Quotient Signed, pg. 471.
:quos ar, as, at is op2 = 0b1101 & op1 = 0b0010 & ar & as & at & op0 = 0 {
ar = as s/ at;
}
# QUOU - Quotient Unsigned, pg. 472.
:quou ar, as, at is op2 = 0b1100 & op1 = 0b0010 & ar & as & at & op0 = 0 {
ar = as / at;
}
# RDTLB0 - Read Data TLB Virtual Entry, pg. 473.
:rdtlb0 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1011 & as & at & op0 = 0 {
at = rdtlb0(as);
}
# RDTLB1 - Read Data TLB Entry Translation, pg. 474.
:rdtlb1 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1111 & as & at & op0 = 0 {
at = rdtlb1(as);
}
# REMS - Remainder Signed, pg. 475.
:rems ar, as, at, is op2 = 0b1111 & op1 = 0b0010 & ar & as & at & op0 = 0 {
ar = as s% at;
}
# REMU - Remainder Unsigned, pg. 476.
:remu ar, as, at, is op2 = 0b1110 & op1 = 0b0010 & ar & as & at & op0 = 0 {
ar = as % at;
}
# RER - Read External Register, pg. 477.
:rer as, at is op2 = 0b0100 & op1 = 0 & ar = 0b0110 & as & at & op0 = 0 {
as = rer(at);
}
# RET.N - Narrow Non-Windowed Return, pg. 479.
:ret.n is n_ar = 0b1111 & n_as = 0 & n_at = 0 & n_op0 = 0b1101 {
return [a0];
o2=a2;
}
# RFDD - Return from Debug and Dispatch, pg. 484.
:rfdd is op2 = 0b1111 & op1 = 0b0001 & ar = 0b1110 & (as = 0b0000 | as = 0b0001) & at = 0b0001 & op0 = 0 {
rfdd();
}
# RFDE _ Return From Double Exception, pg. 485.
:rfde is op2 = 0 & op1 = 0 & ar = 0b0011 & as =0b0010 & at = 0 & op0 = 0 {
rfde();
}
# RFDO - Return from Debug Operation, pg. 486.
:rfdo is op2 = 0b1111 & op1 = 0b0001 & ar = 0b1110 & as = 0 & at = 0 & op0 = 0 {
rfdo();
}
# RFE - Return From Exception, pg. 487.
:rfe is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0 & at = 0 & op0 = 0 {
rfe();
}
# RFI - Return from High-Priority Interrupt, pg. 488.
:rfi u4_8.11 is op2 = 0 & op1 = 0 & ar = 0b0011 & u4_8.11 & at = 0b0001 & op0 = 0 {
rfi(u4_8.11:1);
}
# RFME - Return from Memory Error, pg. 489.
:rfme is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0 & at = 0b0010 & op0 = 0 {
rfme();
}
# RFR - Move FR to AR, pg. 490.
:rfr ar, fs is op2 = 0b1111 & op1 = 0b1010 & ar & fs & at = 0b0100 & op0 = 0 {
ar = fs;
}
# RFUE - Return from User-Mode Exception, pg. 491.
:rfue is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0b0001 & at = 0 & op0 = 0 {
rfue();
}
# RFWO - Return from Window Overflow, pg. 492.
:rfwo is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0b0100 & at = 0 & op0 = 0 {
rfwo();
}
# RFWU - Return from Window Underflow, pg. 493.
:rfwu is op2 = 0 & op1 = 0 & ar = 0b0011 & as = 0b0101 & at = 0 & op0 = 0 {
rfwu();
}
# RITLB0 - Read Instruction TLB Virtual Entry, pg. 494.
:ritlb0 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0011 & as & at & op0 = 0 {
at = ritlb0(as);
}
# RITLB1 - Read Instruction TLB Entry Translation, pg. 495.
:ritlb1 at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0111 & as & at & op0 = 0 {
at = ritlb1(as);
}
# ROUND.S - Round Single to Fixed, pg. 497.
:round.s ar, fs, u4_4.7 is op2 = 0b1000 & op1 = 0b1010 & ar & fs & u4_4.7 & op0 = 0 {
local scale:4 = int2float(1:2 << u4_4.7:2);
ar = round(fs f* scale);
}
# RSIL - Read and Set Interrupt Level, pg. 498.
:rsil at, u4_8.11 is op2 = 0 & op1 = 0 & ar = 0b0110 & u4_8.11 & at & op0 = 0 {
at = rsil(u4_8.11:1);
}
# RSR - Read Special Register, pg. 500.
:rsr at, u8_8.15 is op0 = 0 & op1 = 0b0011 & u8_8.15 & at & op0 = 0 {
local src:4 = zext(u8_8.15:1);
at = rsr(u8_8.15:1);
at = *[special_register]:4 src;
}
# RSYNC - Register Read Synchronize, pg. 502.
:rsync is op2 = 0 & op1 = 0 & ar = 0b0010 & as = 0 & at = 0b0001 & op0 = 0 {
rsync();
}
# RUR - Read User Register, pg. 503.
:rur ar, u8_4.11 is op2 = 0b1110 & op1 = 0b0011 & ar & u8_4.11 & op0 = 0 {
ar = rur(u8_4.11:1);
}
# S8I - Store 8-bit, pg. 504.
:s8i at, as, u8_16.23 is u8_16.23 & ar = 0b0100 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u8_16.23:1);
*:1 addr = at:1;
}
# S16I - Store 16-bit, pg. 505.
:s16i at, as, u9_16.23_sb1 is u9_16.23_sb1 & ar = 0b0101 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u9_16.23_sb1);
*:2 addr = at:2;
}
# S32C1I - Store 32-bit Compare Conditional, pg. 506
:s32c1i at, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b1110 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u10_16.23_sb2);
at = s32c1i(addr);
}
# S32I - Store 32-bit, pg. 510.
:s32i at, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0110 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u10_16.23_sb2);
*:4 addr = at;
}
# S32I.N - Narrow Store 32-bit, pg. 512.
:s32i.n n_at, n_as, n_u6_12.15_sb2 is n_u6_12.15_sb2 & n_as & n_at & n_op0 = 0b1001 {
local addr:4 = n_as + zext(n_u6_12.15_sb2);
*:4 addr = n_at;
}
# S32RI - Store 32-bit Release, pg. 514.
:s32ri at, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b1111 & as & at & op0 = 0b0010 {
local addr:4 = as + zext(u10_16.23_sb2);
*:4 addr = at;
release(addr);
}
# SDCT - Store Data Cache Tag, pg. 516.
:sdct at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b1001 & as & at & op0 = 0 {
sdct(as, at);
}
# SEXT - Sign Extend, pg. 518.
:sext ar, as, u5_4.7_plus7 is op2 = 0b0010 & op1 = 0b0011 & ar & as & u5_4.7_plus7 & op0 = 0 {
local shift:1 = 31:1 - u5_4.7_plus7;
local tmp:4 = as << shift;
ar = tmp s>> shift;
}
# SICT - Store Instruction Cache Tag, pg. 519.
:sict at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b0001 & as & at & op0 = 0 {
sict(as, at);
}
# SICW - Store Instruction Cache word, pg. 521.
:sicw at, as is op2 = 0b1111 & op1 = 0b0001 & ar = 0b0011 & as & at & op0 = 0 {
sicw(as, at);
}
# SIMCALL - Simulator Call, pg. 523.
:simcall is op2 = 0 & op1 = 0 & ar = 0b0101 & as = 0b0001 & at = 0 & op0 = 0 {
simcall();
}
# SLL - Shift Left Logical, pg. 524.
:sll ar, as is op2 = 0b1010 & op1 = 0b0001 & ar & as & at = 0 & op0 = 0 {
local sa:1 = 32 - sar;
ar = as << sa;
}
# SLLI - Shift Left Logical Immediate, pg. 525.
:slli ar, as, u5_4.7_20 is u3_21.23 = 0 & u1_20 & u5_4.7_20 & op1 = 0b0001 & ar & as & op0 = 0 {
local sa:1 = 32 - 16 * u1_20 - u5_4.7_20;
ar = as << sa;
}
# SRA - Shift Right Arithmetic, pg. 526.
:sra ar, at is op2 = 0b1011 & op1 = 0b0001 & ar & as = 0 & at & op0 = 0 {
ar = at s>> sar;
}
# SRAI - Shift Right Arithmetic Immediate, pg. 527.
:srai ar, at, u5_8.11_20 is u3_21.23 = 0b001 & u5_8.11_20 & op1 = 0b0001 & ar & at & op0 = 0 {
ar = at s>> u5_8.11_20;
}
# SRC - Shift Right Combined, pg. 528.
:src ar, as, at is op2 = 0b1000 & op1 = 0b0001 & ar & as & at & op0 = 0 {
local s64:8 = zext(as);
local t64:8 = zext(at);
local combined:8 = (s64 << 32) | t64;
local shifted:8 = combined >> sar;
ar = shifted:4;
}
# SRL - Shift Right Logical, pg. 529.
:srl ar, at is op2 = 0b1001 & op1 = 0b0001 & ar & as = 0 & at & op0 = 0 {
ar = at >> sar;
}
# SRLI - Shift Right Logical Immediate, pg. 530.
:srli ar, at, u4_8.11 is op2 = 0b0100 & op1 = 0b0001 & ar & u4_8.11 & at & op0 = 0 {
ar = at >> u4_8.11;
}
# SSA8B - Set Shift Amount for BE Byte Shift, pg. 531.
:ssa8b as is op2 = 0b0100 & op1 = 0 & ar = 0b0011 & as & at = 0 & op0 = 0 {
local lsa:4 = (as&3)*8;
sar = 32 - lsa:1;
}
# SSA8L - Set Shift Amount for LE Byte Shift, pg. 532.
:ssa8l as is op2 = 0b0100 & op1 = 0 & ar = 0b0010 & as & at = 0 & op0 = 0 {
local rsa:4 = (as&3)*8;
sar = rsa:1;
}
# SSAI - Set Shift Amount Immediate, pg. 533.
:ssai u5_8.11_4 is op2 = 0b0100 & op1 = 0 & ar = 0b0100 & u5_8.11_4 & u3_5.7 = 0 & op0 = 0 {
sar = u5_8.11_4:1;
}
# SSI - Store Single Immediate, pg. 534.
:ssi ft, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b0100 & as & ft & op0 = 0b0011 {
local addr:4 = as + zext(u10_16.23_sb2);
*:4 addr = ft;
}
# SSIU - Store Single Immediate with Update, pg. 536.
:ssiu ft, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0b1100 & as & ft & op0 = 0b0011 {
local addr:4 = as + zext(u10_16.23_sb2);
*:4 addr = ft;
as = addr;
}
# SSL - Set Shift Amount for Left Shift, pg. 538.
:ssl as is op2 = 0b0100 & op1 = 0 & ar = 0b0001 & as & at = 0 & op0 = 0 {
sar = 32 - (as:1 & 0x1f);
}
# SSR - Set Shift Amount for Right Shift, pg. 539.
:ssr as is op2 = 0b0100 & op1 = 0 & ar = 0 & as & at = 0 & op0 = 0 {
sar = (as:1 & 0x1f);
}
# SSX - Store Singe Indexed, pg. 540.
:ssx fr, as, at is op2 = 0b0100 & op1 = 0b1000 & fr & as & at & op0 = 0 {
local addr:4 = as+at;
*:4 addr = fr;
}
# SSXU - Store Singe Indexed with Update, pg. 541.
:ssxu fr, as, at is op2 = 0b0101 & op1 = 0b1000 & fr & as & at & op0 = 0 {
local addr:4 = as+at;
*:4 addr = fr;
as = addr;
}
# SUB - Subtract, pg. 542.
:sub ar, as, at is op2 = 0b1100 & op1 = 0 & ar & as & at & op0 = 0 {
ar = as - at;
}
# SUB.S - Subtract Single, pg. 543.
:sub.s fr, fs, ft is op2 = 0b0001 & op1 = 0b1010 & fr & fs & ft & op0 = 0 {
fr = fs f- ft;
}
# SUBX2 - Subtract with Shift by 1, pg. 544.
:subx2 ar, as, at is op2 = 0b1101 & op1 = 0 & ar & as & at & op0 = 0 {
ar = (as << 1) - at;
}
# SUBX4 - Subtract with Shift by 2, pg. 545.
:subx4 ar, as, at is op2 = 0b1110 & op1 = 0 & ar & as & at & op0 = 0 {
ar = (as << 2) - at;
}
# SUBX8 - Subtract with Shift by 3, pg. 546.
:subx8 ar, as, at is op2 = 0b1111 & op1 = 0 & ar & as & at & op0 = 0 {
ar = (as << 3) - at;
}
# SYSCALL - System Call, pg. 547.
:syscall is op2 = 0 & op1 = 0 & ar = 0b0101 & as = 0 & at = 0 & op0 = 0 {
syscall();
}
# TRUNC.S - Truncate Single to Fixed, pg. 548
:trunc.s ar, fs, u4_4.7 is op2 = 0b1001 & op1 = 0b1010 & ar & fs & u4_4.7 & op0 = 0 {
local scale:4 = int2float(1:2 << u4_4.7:2);
ar = trunc(fs f* scale);
}
# UEQ.S - Compare Single Unordered or Equal, pg. 549.
:ueq.s br, fs, ft is op2 = 0b0011 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
br = nan(fs) || nan(ft) || fs f== ft;
}
# UFLOAT.S - Convert Unsigned Fixed to Single, pg. 550.
:ufloat.s fr, as, u4_4.7 is op2 = 0b1101 & op1 = 0b1010 & fr & as & u4_4.7 & op0 = 0 {
local tmp:8 = zext(as);
local f = int2float(tmp);
local d = int2float(1:2 << u4_4.7:2);
fr = d f/ f;
}
# ULE.S - Compare Single Unordered or Less Than or Equal, pg. 551.
:ule.s br, fs, ft is op2 = 0b0111 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
br = nan(fs) || nan(ft) || fs f<= ft;
}
# ULT.S - Compare Single Unordered or Less Than, pg. 552.
:ult.s br, fs, ft is op2 = 0b0101 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
br = nan(fs) || nan(ft) || fs f< ft;
}
# FIXME: UMUL.AA*
# UN.S - Compare Single Unordered, pg. 554.
:un.s br, fs, ft is op2 = 0b0001 & op1 = 0b1011 & br & fs & ft & op0 = 0 {
br = nan(fs) || nan(ft);
}
# UTRUNC.S - Truncate Single to Fixed Unsigned, pg. 555.
:utrunc.s ar, fs, u4_4.7 is op2 = 0b1110 & op1 = 0b1010 & ar & fs & u4_4.7 & op0 = 0 {
local scale:4 = int2float(1:2 << u4_4.7:2);
local tmp:8 = trunc(fs f* scale);
local posof = nan(fs) || (tmp >> 16) != 0;
local negof = tmp s< 0;
local noof = !posof && !negof;
ar = zext(posof)*0xffffffff + zext(negof)*0x80000000 + zext(noof)*tmp:4;
}
# WAITI - Wait Interrupt, pg. 556.
:waiti u4_8.11 is op2 = 0 & op1 = 0 & ar = 0b0111 & u4_8.11 & at = 0 & op0 = 0 {
waiti(u4_8.11:4);
}
# WDTLB - Write Data TLB Entry, pg. 557.
:wdtlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b1110 & as & at & op0 = 0 {
wdtlb(as, at);
}
# WER - Write External Register, pg. 558.
:wer as, at is op2 = 0b0100 & op1 = 0 & ar = 0b0111 & as & at & op0 = 0 {
wer(as, at);
}
# WFR - Move AR to FR, pg. 559.
:wfr fr, as is op2 = 0b1111 & op1 = 0b1010 & fr & as & at = 0b0101 & op0 = 0 {
fr = as;
}
# WITLB - Write Instruction TLB Entry, pg. 560.
:witlb at, as is op2 = 0b0101 & op1 = 0 & ar = 0b0110 & as & at & op0 = 0 {
witlb(as, at);
}
# WSR - Write Special Register, pg. 561.
:wsr at, u8_8.15 is op2 = 0b0001 & op1 = 0b0011 & u8_8.15 & at & op0 = 0 {
local dst:4 = zext(u8_8.15:1);
*[special_register]:4 dst = at;
wsr(u8_8.15:1, at);
}
#:WSR.^sr at is op2=0x1 & op1=0x3 & sr & at & op0=0x0
#{
# *[special_register]:4 sr = at;
#}
# WUR - Write User Register, pg. 563.
:wur at, u8_8.15 is op2 = 0b1111 & op1 = 0b0011 & u8_8.15 & at & op0 = 0 {
wur(u8_8.15:1, at);
}
# XOR - Bitwise Exclusive Or, pg. 564.
:xor ar, as, at is op2 = 0b0011 & op1 = 0 & ar & as & at & op0 = 0 {
ar = as ^ at;
}
# XORB - Boolean Exclusive Or, pg. 565.
:xorb br, bs, bt is op2 = 0b0100 & op1 = 0b0010 & br & bs & bt & op0 = 0 {
br = bs ^^ bt;
}
# XSR - Exchange Special Register, pg. 566.
:xsr at, u8_8.15 is op2 = 0b0110 & op1 = 0b0001 & u8_8.15 & at & op0 = 0 {
at = xsr(u8_8.15:1, at);
}
# PAD, dummy
#:pad is op0_16=0x0 {
#}
# PAD, dummy
#:pad is op0_8=0x0 {
#}