GP-1135 addressing code review, replaces major version change with minor version change

GP-1135 added explanatory comment
GP-1135 fixes to SPARC - updated major version of language
This commit is contained in:
James
2021-08-13 09:41:38 -04:00
parent 1db67799b6
commit ea7de5e5af
2 changed files with 327 additions and 183 deletions

View File

@@ -5,7 +5,7 @@
endian="big" endian="big"
size="32" size="32"
variant="default" variant="default"
version="1.3" version="1.4"
slafile="SparcV9_32.sla" slafile="SparcV9_32.sla"
processorspec="SparcV9.pspec" processorspec="SparcV9.pspec"
manualindexfile="../manuals/Sparc.idx" manualindexfile="../manuals/Sparc.idx"
@@ -19,7 +19,7 @@
endian="big" endian="big"
size="64" size="64"
variant="default" variant="default"
version="1.3" version="1.4"
slafile="SparcV9_64.sla" slafile="SparcV9_64.sla"
processorspec="SparcV9.pspec" processorspec="SparcV9.pspec"
manualindexfile="../manuals/Sparc.idx" manualindexfile="../manuals/Sparc.idx"

View File

@@ -34,13 +34,18 @@ define register offset=0x3000 size=1 [ x_nf x_zf x_vf x_cf i_nf i_zf i_vf i_cf ]
define register offset=0x4000 size=1 [ ASI ]; define register offset=0x4000 size=1 [ ASI ];
define register offset=0x4008 size=1 [ FPRS ]; define register offset=0x4008 size=1 [ FPRS ];
define register offset=0x5000 size=2 [ fsr ]; define register offset=0x5000 size=$(SIZE) [ fsr ];
define register offset=0x5002 size=1 [ fcc0 fcc1 fcc2 fcc3 ]; #fcc0 is bits 10 and 11 of fsr
#fcc1 is bits 32 and 33 of fsr (64 bit only)
#fcc2 is bits 34 and 35 of fsr (64 bit only)
#fcc3 is bits 36 and 37 of fsr (64 bit only)
#model these as separate 1-byte varnodes
define register offset=0x5008 size=1 [ fcc0 fcc1 fcc2 fcc3 ];
define register offset=0x5010 size=1 [ didrestore ]; define register offset=0x5010 size=1 [ didrestore ];
define register offset=0x5020 size=1 [ DECOMPILE_MODE ]; # Fake register define register offset=0x5020 size=1 [ DECOMPILE_MODE ]; # Fake register
define register offset=0x5000 size=$(SIZE) [ define register offset=0x6000 size=$(SIZE) [
TPC1 TPC2 TPC3 TPC4 TPC1 TPC2 TPC3 TPC4
TNPC1 TNPC2 TNPC3 TNPC4 TNPC1 TNPC2 TNPC3 TNPC4
TSTATE1 TSTATE2 TSTATE3 TSTATE4 TSTATE1 TSTATE2 TSTATE3 TSTATE4
@@ -50,7 +55,7 @@ define register offset=0x5000 size=$(SIZE) [
OTHERWIN WSTATE FQ VER GL OTHERWIN WSTATE FQ VER GL
]; ];
define register offset=0x6000 size=$(SIZE) [ define register offset=0x7000 size=$(SIZE) [
HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4 HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4
HTSTATE1 HTSTATE2 HTSTATE3 HTSTATE4 HTSTATE1 HTSTATE2 HTSTATE3 HTSTATE4
RESV2_1 RESV2_2 RESV2_3 RESV2_4 RESV2_1 RESV2_2 RESV2_3 RESV2_4
@@ -87,7 +92,7 @@ define register offset=0x6000 size=$(SIZE) [
# i7 w017 w037 w127 w217 w237 w327 w417 # i7 w017 w037 w127 w217 w237 w327 w417
# o7 w037 w127 w217 w237 w327 w417 # o7 w037 w127 w217 w237 w327 w417
define register offset=0x7000 size=$(SIZE) [ define register offset=0x8000 size=$(SIZE) [
w010 w011 w012 w013 w014 w015 w016 w017 w010 w011 w012 w013 w014 w015 w016 w017
w020 w021 w022 w023 w024 w025 w026 w027 w020 w021 w022 w023 w024 w025 w026 w027
w030 w031 w032 w033 w034 w035 w036 w037 w030 w031 w032 w033 w034 w035 w036 w037
@@ -137,7 +142,6 @@ define register offset=0x2000 size=16 [
define pcodeop segment; define pcodeop segment;
define pcodeop popc;
define pcodeop sw_trap; define pcodeop sw_trap;
define pcodeop reset; define pcodeop reset;
@@ -203,6 +207,7 @@ define token instr(32)
opf6 = ( 5,10) opf6 = ( 5,10)
opf_cc = (11,13) opf_cc = (11,13)
opf_low = ( 5,10) opf_low = ( 5,10)
opf_low_5_9 = ( 5,9)
fcn = (25,29) fcn = (25,29)
swtrap = ( 0, 6) swtrap = ( 0, 6)
bit28 = (28,28) bit28 = (28,28)
@@ -333,14 +338,21 @@ if (DECOMPILE_MODE) goto <skip_rotate>;
<skip_rotate> <skip_rotate>
} }
#Register g0 in Sparc is always 0
#There are special cases for source operands RS1 and RS2 which just return the constant 0 when the
#specified register is g0
RS1: rs1 is rs1 & rs1_zero=0 { export 0:$(SIZE); } RS1: rs1 is rs1 & rs1_zero=0 { export 0:$(SIZE); }
RS1: rs1 is rs1 { export rs1; } RS1: rs1 is rs1 { export rs1; }
RS2: rs2 is rs2 & rs2_zero=0 { export 0:$(SIZE); } RS2: rs2 is rs2 & rs2_zero=0 { export 0:$(SIZE); }
RS2: rs2 is rs2 { export rs2; } RS2: rs2 is rs2 { export rs2; }
RD: rd is rd & rd_zero=0 { export 0:$(SIZE); } #For the destination operand RD, we export a temporary varnode with value 0.
RD: rd is rd & rd_zero { export rd; } #This is because writes to g0 are allowed, but they have no visible effect (see the Sparc manual).
#This way the value of g0 won't appear to change when using the pcode emulator.
RD: rd is rd & rd_zero=0 { local tmp:$(SIZE) = 0; export tmp; }
RD: rd is rd { export rd; }
regorimm: RS2 is i=0 & RS2 { export RS2; } regorimm: RS2 is i=0 & RS2 { export RS2; }
regorimm: simm13 is i=1 & simm13 { export *[const]:$(SIZE) simm13; } regorimm: simm13 is i=1 & simm13 { export *[const]:$(SIZE) simm13; }
@@ -392,6 +404,40 @@ macro addflags32(op1,op2) {
i_vf = scarry(op1,op2); i_vf = scarry(op1,op2);
} }
macro addCarryFlags ( op1, op2 ) {
local op1_low_32:4 = op1:4;
local op2_low_32:4 = op2:4;
local CFcopy:$(SIZE) = zext(i_cf);
local CFcopy_32:4 = zext(i_cf);
i_cf = carry( op1_low_32, op2_low_32);
x_cf = carry(op1,op2);
i_vf = scarry( op1_low_32, op2_low_32);
x_vf = scarry(op1, op2);
local result:$(SIZE) = op1 + op2;
local result_low_32:4 = op1_low_32 + op2_low_32;
i_cf = i_cf || carry( result_low_32, CFcopy_32 );
x_cf = x_cf || carry(result,CFcopy);
i_vf = i_vf ^^ scarry( result_low_32, CFcopy_32 );
x_vf = x_vf ^^ scarry(result,CFcopy);
}
macro subCarryFlags ( op1, op2 ) {
local op1_low_32:4 = op1:4;
local op2_low_32:4 = op2:4;
local CFcopy:$(SIZE) = zext(i_cf);
local CFCopy_32:4 = zext(i_cf);
i_cf = op1_low_32 < op2_low_32;
x_cf = op1 < op2;
i_vf = sborrow( op1_low_32, op2_low_32);
x_vf = sborrow(op1, op2);
local result:$(SIZE) = op1 - op2;
local result_low_32:4 = op1_low_32 - op2_low_32;
i_cf = i_cf || (result_low_32 < CFCopy_32);
x_cf = x_cf || (result < CFcopy);
i_vf = i_vf ^^ sborrow( result_low_32, CFCopy_32);
x_vf = x_vf ^^ sborrow(result,CFcopy);
}
macro logicflags() { macro logicflags() {
x_cf = 0; x_cf = 0;
x_vf = 0; x_vf = 0;
@@ -411,6 +457,11 @@ macro subflags(op1,op2) {
i_vf = sborrow(tmp1,tmp2); i_vf = sborrow(tmp1,tmp2);
} }
macro tsubflags(op1,op2){
subflags(op1,op2);
i_vf = i_vf || ((op1 & 0x3) != 0) || ((op2 & 0x3) != 0);
}
macro zeroflags(op1) { macro zeroflags(op1) {
x_zf = (op1 == 0); x_zf = (op1 == 0);
x_nf = (op1 s< 0); x_nf = (op1 s< 0);
@@ -437,84 +488,101 @@ macro unpackflags(ccr) {
} }
# --------------- # ---------------
:add RS1,regorimm,rd is op=2 & rd & op3=0x0 & RS1 & regorimm {rd = RS1 + regorimm;} :add RS1,regorimm,RD is op=2 & RD & op3=0x0 & RS1 & regorimm {RD = RS1 + regorimm;}
:addcc RS1,regorimm,rd is op=2 & rd & op3=0x10 & RS1 & regorimm {addflags(RS1,regorimm); :addcc RS1,regorimm,RD is op=2 & RD & op3=0x10 & RS1 & regorimm
rd = RS1 + regorimm; {
zeroflags(rd); addflags(RS1,regorimm);
RD = RS1 + regorimm;
zeroflags(RD);
} }
:addc RS1,regorimm,rd is op=2 & rd & op3=0x8 & RS1 & regorimm {rd = RS1 + regorimm + zext(i_cf);} :addc RS1,regorimm,RD is op=2 & RD & op3=0x8 & RS1 & regorimm {RD = RS1 + regorimm + zext(i_cf);}
:addccc RS1,regorimm,RD is op=2 & RD & op3=0x18 & RS1 & regorimm
:addccc RS1,regorimm,rd is op=2 & rd & op3=0x18 & RS1 & regorimm {addflags(RS1,regorimm); {
rd = RS1 + regorimm + zext(i_cf); local original_i_cf:$(SIZE) = zext(i_cf);
zeroflags(rd); addCarryFlags(RS1,regorimm);
RD = RS1 + regorimm + original_i_cf;
zeroflags(RD);
} }
#----------------------- #-----------------------
:and RS1,regorimm,rd is op=2 & rd & op3=0x1 & RS1 & regorimm {rd = RS1 & regorimm;} :and RS1,regorimm,RD is op=2 & RD & op3=0x1 & RS1 & regorimm {RD = RS1 & regorimm;}
:andcc RS1,regorimm,rd is op=2 & rd & op3=0x11 & RS1 & regorimm {logicflags(); :andcc RS1,regorimm,RD is op=2 & RD & op3=0x11 & RS1 & regorimm
rd = RS1 & regorimm; {
zeroflags(rd); logicflags();
RD = RS1 & regorimm;
zeroflags(RD);
} }
:andn RS1,regorimm,rd is op=2 & rd & op3=0x5 & RS1 & regorimm {rd = RS1 & ~regorimm;} :andn RS1,regorimm,RD is op=2 & RD & op3=0x5 & RS1 & regorimm {RD = RS1 & ~regorimm;}
:andncc RS1,regorimm,rd is op=2 & rd & op3=0x15 & RS1 & regorimm {logicflags(); :andncc RS1,regorimm,RD is op=2 & RD & op3=0x15 & RS1 & regorimm
rd = RS1 & ~regorimm; {
zeroflags(rd); logicflags();
RD = RS1 & ~regorimm;
zeroflags(RD);
} }
:or RS1,regorimm,rd is op=2 & rd & op3=0x2 & RS1 & regorimm {rd = RS1 | regorimm;} :or RS1,regorimm,RD is op=2 & RD & op3=0x2 & RS1 & regorimm {RD = RS1 | regorimm;}
:orcc RS1,regorimm,rd is op=2 & rd & op3=0x12 & RS1 & regorimm {logicflags(); :orcc RS1,regorimm,RD is op=2 & RD & op3=0x12 & RS1 & regorimm
rd = RS1 | regorimm; {
zeroflags(rd); logicflags();
RD = RS1 | regorimm;
zeroflags(RD);
} }
:orn RS1,regorimm,rd is op=2 & rd & op3=0x6 & RS1 & regorimm {rd = RS1 | ~regorimm;} :orn RS1,regorimm,RD is op=2 & RD & op3=0x6 & RS1 & regorimm {RD = RS1 | ~regorimm;}
:orncc RS1,regorimm,rd is op=2 & rd & op3=0x16 & RS1 & regorimm {logicflags(); :orncc RS1,regorimm,RD is op=2 & RD & op3=0x16 & RS1 & regorimm
rd = RS1 | ~regorimm; {
zeroflags(rd); logicflags();
RD = RS1 | ~regorimm;
zeroflags(RD);
} }
:xor RS1,regorimm,rd is op=2 & rd & op3=0x3 & RS1 & regorimm {rd = RS1 ^ regorimm;} :xor RS1,regorimm,RD is op=2 & RD & op3=0x3 & RS1 & regorimm {RD = RS1 ^ regorimm;}
:xorcc RS1,regorimm,rd is op=2 & rd & op3=0x13 & RS1 & regorimm {logicflags(); :xorcc RS1,regorimm,RD is op=2 & RD & op3=0x13 & RS1 & regorimm
rd = RS1 ^ regorimm; {
zeroflags(rd); logicflags();
RD = RS1 ^ regorimm;
zeroflags(RD);
} }
:xnor RS1,regorimm,rd is op=2 & rd & op3=0x7 & RS1 & regorimm {rd = RS1 ^ ~regorimm;}
:xnorcc RS1,regorimm,rd is op=2 & rd & op3=0x17 & RS1 & regorimm {logicflags(); :xnor RS1,regorimm,RD is op=2 & RD & op3=0x7 & RS1 & regorimm {RD = RS1 ^ ~regorimm;}
rd = RS1 ^ ~regorimm;
zeroflags(rd); :xnorcc RS1,regorimm,RD is op=2 & RD & op3=0x17 & RS1 & regorimm
{
logicflags();
RD = RS1 ^ ~regorimm;
zeroflags(RD);
} }
# --------------- # ---------------
:ldsb ea,rd is op=3 & rd & op3=0x09 & ea { rd = sext(*:1 ea); } :ldsb ea,RD is op=3 & RD & op3=0x09 & ea { RD = sext(*:1 ea); }
:ldsh ea,rd is op=3 & rd & op3=0x0A & ea { rd = sext(*:2 ea); } :ldsh ea,RD is op=3 & RD & op3=0x0A & ea { RD = sext(*:2 ea); }
:ldsw ea,rd is op=3 & rd & op3=0x08 & ea { rd = sext(*:4 ea); } :ldsw ea,RD is op=3 & RD & op3=0x08 & ea { RD = sext(*:4 ea); }
:ldub ea,rd is op=3 & rd & op3=0x01 & ea { rd = zext(*:1 ea); } :ldub ea,RD is op=3 & RD & op3=0x01 & ea { RD = zext(*:1 ea); }
:lduh ea,rd is op=3 & rd & op3=0x02 & ea { rd = zext(*:2 ea); } :lduh ea,RD is op=3 & RD & op3=0x02 & ea { RD = zext(*:2 ea); }
:lduw ea,rd is op=3 & rd & op3=0x00 & ea { rd = zext(*:4 ea); } :lduw ea,RD is op=3 & RD & op3=0x00 & ea { RD = zext(*:4 ea); }
:ldx ea,rd is op=3 & rd & op3=0x0b & ea { rd = *:$(SIZE) ea; } :ldx ea,RD is op=3 & RD & op3=0x0b & ea { RD = *:$(SIZE) ea; }
@if SIZE=="8" @if SIZE=="8"
:ldd ea,rd is op=3 & rd & op3=0x03 & ea { rd = *:$(SIZE) ea; } :ldd ea,RD is op=3 & RD & op3=0x03 & ea { RD = *:$(SIZE) ea; }
@else @else
:ldd ea,rd is op=3 & rd & rd_d & op3=0x03 & ea { rd_d = *:8 ea; } :ldd ea,RD is op=3 & RD & rd_d & op3=0x03 & ea { rd_d = *:8 ea; }
@endif @endif
:ldsba ea_alt,rd is op=3 & rd & op3=0x19 & ea_alt { rd = sext(*:1 ea_alt); } :ldsba ea_alt,RD is op=3 & RD & op3=0x19 & ea_alt { RD = sext(*:1 ea_alt); }
:ldsha ea_alt,rd is op=3 & rd & op3=0x1a & ea_alt { rd = sext(*:2 ea_alt); } :ldsha ea_alt,RD is op=3 & RD & op3=0x1a & ea_alt { RD = sext(*:2 ea_alt); }
:ldswa ea_alt,rd is op=3 & rd & op3=0x18 & ea_alt { rd = sext(*:4 ea_alt); } :ldswa ea_alt,RD is op=3 & RD & op3=0x18 & ea_alt { RD = sext(*:4 ea_alt); }
:lduba ea_alt,rd is op=3 & rd & op3=0x11 & ea_alt { rd = zext(*:1 ea_alt); } :lduba ea_alt,RD is op=3 & RD & op3=0x11 & ea_alt { RD = zext(*:1 ea_alt); }
:lduha ea_alt,rd is op=3 & rd & op3=0x12 & ea_alt { rd = zext(*:2 ea_alt); } :lduha ea_alt,RD is op=3 & RD & op3=0x12 & ea_alt { RD = zext(*:2 ea_alt); }
:lduwa ea_alt,rd is op=3 & rd & op3=0x10 & ea_alt { rd = zext(*:4 ea_alt); } :lduwa ea_alt,RD is op=3 & RD & op3=0x10 & ea_alt { RD = zext(*:4 ea_alt); }
:ldxa ea_alt,rd is op=3 & rd & op3=0x1b & ea_alt { rd = *:$(SIZE) ea_alt; } :ldxa ea_alt,RD is op=3 & RD & op3=0x1b & ea_alt { RD = *:$(SIZE) ea_alt; }
:ldda ea_alt,rd is op=3 & rd & op3=0x13 & ea_alt { rd = *:$(SIZE) ea_alt; } :ldda ea_alt,RD is op=3 & RD & op3=0x13 & ea_alt { RD = *:$(SIZE) ea_alt; }
#----------------- #-----------------
:stb RD,ea is op=3 & RD & op3=0x05 & ea { *ea = RD:1; } :stb RD,ea is op=3 & RD & op3=0x05 & ea { *ea = RD:1; }
@@ -540,18 +608,29 @@ macro unpackflags(ccr) {
:stda RD,ea_alt is op=3 & RD & op3=0x17 & ea_alt { *ea_alt = RD; } :stda RD,ea_alt is op=3 & RD & op3=0x17 & ea_alt { *ea_alt = RD; }
# --------------- # ---------------
:sub RS1,regorimm,rd is op=2 & rd & op3=0x4 & RS1 & regorimm {rd = RS1 - regorimm;} :sub RS1,regorimm,RD is op=2 & RD & op3=0x4 & RS1 & regorimm
{
:subcc RS1,regorimm,rd is op=2 & rd & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm); RD = RS1 - regorimm;
rd = RS1 - regorimm;
zeroflags(rd);
} }
:subc RS1,regorimm,rd is op=2 & rd & op3=0xc & RS1 & regorimm {rd = RS1 - regorimm - zext(i_cf);} :subcc RS1,regorimm,RD is op=2 & RD & op3=0x14 & RS1 & regorimm
{
subflags(RS1,regorimm);
RD = RS1 - regorimm;
zeroflags(RD);
}
:subccc RS1,regorimm,rd is op=2 & rd & op3=0x1c & RS1 & regorimm {subflags(RS1,regorimm); :subc RS1,regorimm,RD is op=2 & RD & op3=0xc & RS1 & regorimm
rd = RS1 - regorimm - zext(i_cf); {
zeroflags(rd); RD = RS1 - regorimm - zext(i_cf);
}
:subccc RS1,regorimm,RD is op=2 & RD & op3=0x1c & RS1 & regorimm
{
local original_cf:$(SIZE) = zext(i_cf);
subCarryFlags(RS1,regorimm);
RD = RS1 - regorimm - original_cf;
zeroflags(RD);
} }
# --------------- # ---------------
@@ -560,7 +639,9 @@ macro unpackflags(ccr) {
# ---------------COMPARES # ---------------COMPARES
:cmp RS1,regorimm is op=0x2 & rd=0x0 & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm); :cmp RS1,regorimm is op=0x2 & rd=0x0 & op3=0x14 & RS1 & regorimm
{
subflags(RS1,regorimm);
local tmp = RS1 - regorimm; local tmp = RS1 - regorimm;
zeroflags(tmp); zeroflags(tmp);
} }
@@ -568,7 +649,7 @@ macro unpackflags(ccr) {
# ---------------MOVES # ---------------MOVES
:mov regorimm,rd is op=2 & rd & op3=0x2 & rs1=0 & regorimm {rd = regorimm;} :mov regorimm,RD is op=2 & RD & op3=0x2 & rs1=0 & regorimm {RD = regorimm;}
# This will not work until the rs1 field in a token can be used without being # This will not work until the rs1 field in a token can be used without being
# part of the display portion below # part of the display portion below
@@ -579,9 +660,10 @@ RCOND: "nz" is rcond3=5 & RS1 { tmp:1 = (RS1 != 0); export tmp; }
RCOND: "gz" is rcond3=6 & RS1 { tmp:1 = (RS1 s> 0); export tmp; } RCOND: "gz" is rcond3=6 & RS1 { tmp:1 = (RS1 s> 0); export tmp; }
RCOND: "gez" is rcond3=7 & RS1 { tmp:1 = (RS1 s>= 0); export tmp; } RCOND: "gez" is rcond3=7 & RS1 { tmp:1 = (RS1 s>= 0); export tmp; }
:movr^RCOND RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RCOND & regorimm10 & RS1 { :movr^RCOND RS1,regorimm10,RD is op=0x2 & RD & op3=0x2f & RCOND & regorimm10 & RS1
{
if !RCOND goto <movrend>; if !RCOND goto <movrend>;
rd = regorimm10; RD = regorimm10;
<movrend> <movrend>
} }
@@ -631,9 +713,11 @@ m_cc:m_xcc is cc2_4=1 & cc1_4=1 & cc0_4=0 & m_xcc { export m_xcc; }
MICC: "%icc" is cc2_4=1 &cc1_4=0 { } MICC: "%icc" is cc2_4=1 &cc1_4=0 { }
MICC: "%xcc" is cc2_4=1 &cc1_4=1 { } MICC: "%xcc" is cc2_4=1 &cc1_4=1 { }
:mov^m_cc MICC,regorimm11,rd is op=0x2 & rd & op3=0x2c & m_cc & MICC & regorimm11 { #conditional integer moves with floating-point conditions defined in constructor :mov^fmfcc
:mov^m_cc MICC,regorimm11,RD is op=0x2 & RD & op3=0x2c & bit18=1 & m_cc & MICC & regorimm11
{
if (!m_cc) goto <movend>; if (!m_cc) goto <movend>;
rd = regorimm11; RD = regorimm11;
<movend> <movend>
} }
@@ -736,81 +820,112 @@ callreloff: reloc is disp30 [reloc=inst_start+4*disp30;] { export *:$(SIZE) rel
#----------------MULTIPLY AND DIVIDE 64 bit #----------------MULTIPLY AND DIVIDE 64 bit
:mulx RS1,regorimm,rd is op=2 & rd & op3=0x09 & RS1 & regorimm {rd = RS1 * regorimm;} :mulx RS1,regorimm,RD is op=2 & RD & op3=0x09 & RS1 & regorimm {RD = RS1 * regorimm;}
:sdivx RS1,regorimm,rd is op=2 & rd & op3=0x2d & RS1 & regorimm {rd = RS1 s/ regorimm;} :sdivx RS1,regorimm,RD is op=2 & RD & op3=0x2d & RS1 & regorimm {RD = RS1 s/ regorimm;}
:udivx RS1,regorimm,rd is op=2 & rd & op3=0x0d & RS1 & regorimm {rd = RS1 / regorimm;} :udivx RS1,regorimm,RD is op=2 & RD & op3=0x0d & RS1 & regorimm {RD = RS1 / regorimm;}
#----------------MULTIPLY 32 bit #----------------MULTIPLY 32 bit
@if SIZE=="8" @if SIZE=="8"
:umul RS1,regorimm,rd is op=2 & rd & op3=0x0a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32;} :umul RS1,regorimm,RD is op=2 & RD & op3=0x0a & RS1 & regorimm {RD = zext(RS1:4) * zext(regorimm:4); Y=RD>>32;}
:smul RS1,regorimm,rd is op=2 & rd & op3=0x0b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32;} :smul RS1,regorimm,RD is op=2 & RD & op3=0x0b & RS1 & regorimm {RD = sext(RS1:4) * sext(regorimm:4); Y=RD>>32;}
:umulcc RS1,regorimm,rd is op=2 & rd & op3=0x1a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} :umulcc RS1,regorimm,RD is op=2 & RD & op3=0x1a & RS1 & regorimm {RD = zext(RS1:4) * zext(regorimm:4); Y=RD>>32; zeroflags(RD); logicflags();}
:smulcc RS1,regorimm,rd is op=2 & rd & op3=0x1b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} :smulcc RS1,regorimm,RD is op=2 & RD & op3=0x1b & RS1 & regorimm {RD = sext(RS1:4) * sext(regorimm:4); Y=RD>>32; zeroflags(RD); logicflags();}
@else @else
# size = 4 # size = 4
:umul RS1,regorimm,rd is op=2 & rd & op3=0x0a & RS1 & regorimm { :umul RS1,regorimm,RD is op=2 & RD & op3=0x0a & RS1 & regorimm
tmp_RS1:8 = zext(RS1); tmp_regorimm:8 = zext(regorimm); {
tmp:8 = tmp_RS1 * tmp_regorimm; rd = tmp:4; tmp2:8 = tmp >> 32; Y = tmp2:4; tmp_RS1:8 = zext(RS1);
tmp_regorimm:8 = zext(regorimm);
tmp:8 = tmp_RS1 * tmp_regorimm;
RD = tmp:4; tmp2:8 = tmp >> 32;
Y = tmp2:4;
} }
:smul RS1,regorimm,rd is op=2 & rd & op3=0x0b & RS1 & regorimm { :smul RS1,regorimm,RD is op=2 & RD & op3=0x0b & RS1 & regorimm
tmp_RS1:8 = sext(RS1); tmp_regorimm:8 = sext(regorimm); {
tmp:8 = tmp_RS1 * tmp_regorimm; rd = tmp:4; tmp2:8 = tmp >> 32; Y = tmp2:4; tmp_RS1:8 = sext(RS1);
tmp_regorimm:8 = sext(regorimm);
tmp:8 = tmp_RS1 * tmp_regorimm;
RD = tmp:4; tmp2:8 = tmp >> 32;
Y = tmp2:4;
} }
:umulcc RS1,regorimm,rd is op=2 & rd & op3=0x1a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} :umulcc RS1,regorimm,RD is op=2 & RD & op3=0x1a & RS1 & regorimm
:smulcc RS1,regorimm,rd is op=2 & rd & op3=0x1b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} {
RD = zext(RS1:4) * zext(regorimm:4);
Y=RD>>32;
zeroflags(RD);
logicflags();
}
:smulcc RS1,regorimm,RD is op=2 & RD & op3=0x1b & RS1 & regorimm
{
RD = zext(RS1:4) * zext(regorimm:4);
Y=RD>>32;
zeroflags(RD);
logicflags();
}
@endif @endif
#----------------MULTIPLY Step #----------------MULTIPLY Step
:mulscc RS1,regorimm,rd is op=2 & rd & op3=0x24 & RS1 & regorimm { tmp:4 = RS1:4 >> 1; :mulscc RS1,regorimm,RD is op=2 & RD & op3=0x24 & RS1 & regorimm
ccr:4 = zext(i_nf ^^ i_vf); {
local ccr:4 = zext(i_nf ^^ i_vf);
ccr = ccr << 31; ccr = ccr << 31;
tmp = tmp | ccr; local shifted:4 = RS1:4 >> 1;
multiplicand:4 = (Y:4 & 0x1) * regorimm:4; shifted = shifted | ccr;
addflags32(tmp, multiplicand); local addend:4 = 0:4;
tmp = tmp + multiplicand; if ((Y & 0x1) == 0) goto <skip_add>;
rd = zext(tmp); addend = regorimm:4;
zeroflags(rd); <skip_add>
local tbit = (RS1 & 0x1) << 31; local sum:4 = addend + shifted;
Y = (Y >> 1) | tbit; addflags32(addend,shifted);
} #upper 32 bits of RD are undefined according to the manual
local tbit:4 = (RS1:4 & 0x1:4) << 31;
RD = zext(sum);
zeroflags(RD);
#Y is 64 bits in Sparc 9 but the high 32 are fixed to 0
Y = zext((Y:4 >> 1:4) | tbit);
}
#----------------DIVIDE (64-bit / 32-bit) #----------------DIVIDE (64-bit / 32-bit)
# NB- Beware, the plus + operator has higher precdence than shift << # NB- Beware, the plus + operator has higher precedence than shift <<
# (These are Java rules. C rules have shift and + at the same level, so left to right) # (These are Java rules. C rules have shift and + at the same level, so left to right)
:udiv RS1,regorimm,rd is op=2 & rd & op3=0x0e & RS1 & regorimm { :udiv RS1,regorimm,RD is op=2 & RD & op3=0x0e & RS1 & regorimm
{
numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff);
denom:$(SIZE) = regorimm & 0xffffffff; denom:$(SIZE) = regorimm & 0xffffffff;
rd = numerator / denom; RD = numerator / denom;
} }
:sdiv RS1,regorimm,rd is op=2 & rd & op3=0x0f & RS1 & regorimm { :sdiv RS1,regorimm,RD is op=2 & RD & op3=0x0f & RS1 & regorimm
{
numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff);
denom:$(SIZE) = regorimm & 0xffffffff; denom:$(SIZE) = regorimm & 0xffffffff;
rd = numerator s/ denom; RD = numerator s/ denom;
} }
:udivcc RS1,regorimm,rd is op=2 & rd & op3=0x1e & RS1 & regorimm { :udivcc RS1,regorimm,RD is op=2 & RD & op3=0x1e & RS1 & regorimm
{
numerator:$(SIZE)= ( Y << 32) + (RS1 & 0xffffffff); numerator:$(SIZE)= ( Y << 32) + (RS1 & 0xffffffff);
denom:$(SIZE) = regorimm & 0xffffffff; denom:$(SIZE) = regorimm & 0xffffffff;
rd = numerator / denom; RD = numerator / denom;
zeroflags(rd); zeroflags(RD);
i_vf = rd > 0xffffffff; i_vf = RD > 0xffffffff;
i_cf = 0; i_cf = 0;
x_vf = 0; x_vf = 0;
x_cf = 0; x_cf = 0;
} }
:sdivcc RS1,regorimm,rd is op=2 & rd & op3=0x1f & RS1 & regorimm { :sdivcc RS1,regorimm,RD is op=2 & RD & op3=0x1f & RS1 & regorimm
{
numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff);
denom:$(SIZE) = regorimm & 0xffffffff; denom:$(SIZE) = regorimm & 0xffffffff;
rd = numerator s/ denom; RD = numerator s/ denom;
zeroflags(rd); zeroflags(RD);
i_vf = (rd s>= 0x80000000) || (rd s<= -0x7ffffffff); i_vf = (RD s>= 0x80000000) || (RD s<= -0x7ffffffff);
i_cf = 0; i_cf = 0;
x_vf = 0; x_vf = 0;
x_cf = 0; x_cf = 0;
@@ -818,14 +933,14 @@ callreloff: reloc is disp30 [reloc=inst_start+4*disp30;] { export *:$(SIZE) rel
#---------------SHIFT #---------------SHIFT
:sll RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x25 & x=0 & RS1 & reg_or_shcnt { rd=RS1<<reg_or_shcnt; } :sll RS1,reg_or_shcnt,RD is op=0x2 & RD & op3=0x25 & x=0 & RS1 & reg_or_shcnt { RD=RS1<<reg_or_shcnt; }
:srl RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x26 & x=0 & RS1 & reg_or_shcnt { tmp:$(SIZE)=zext(RS1:4); rd=tmp>>reg_or_shcnt; } :srl RS1,reg_or_shcnt,RD is op=0x2 & RD & op3=0x26 & x=0 & RS1 & reg_or_shcnt { tmp:$(SIZE)=zext(RS1:4); RD=tmp>>reg_or_shcnt; }
:sllx RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x25 & x=1 & RS1 & reg_or_shcnt { rd=RS1<<reg_or_shcnt; } :sllx RS1,reg_or_shcnt,RD is op=0x2 & RD & op3=0x25 & x=1 & RS1 & reg_or_shcnt { RD=RS1<<reg_or_shcnt; }
:srlx RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x26 & x=1 & RS1 & reg_or_shcnt { rd=RS1>>reg_or_shcnt; } :srlx RS1,reg_or_shcnt,RD is op=0x2 & RD & op3=0x26 & x=1 & RS1 & reg_or_shcnt { RD=RS1>>reg_or_shcnt; }
:sra RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x27 & x=0 & RS1 & reg_or_shcnt { tmp:4=RS1:4; rd=sext(tmp s>> reg_or_shcnt); } :sra RS1,reg_or_shcnt,RD is op=0x2 & RD & op3=0x27 & x=0 & RS1 & reg_or_shcnt { tmp:4=RS1:4; RD=sext(tmp s>> reg_or_shcnt); }
:srax RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x27 & x=1 & RS1 & reg_or_shcnt { rd=RS1 s>> reg_or_shcnt; } :srax RS1,reg_or_shcnt,RD is op=0x2 & RD & op3=0x27 & x=1 & RS1 & reg_or_shcnt { RD=RS1 s>> reg_or_shcnt; }
# ASR read registers (some ASR #s not permitted for rd: 1, 7..15, other #s handled by rd: 3, 5, 6) # ASR read registers (some ASR #s not permitted for rd: 1, 7..15, other #s handled by rd: 3, 5, 6)
attach variables [ rs_asr ] [ Y _ CCR _ TICK _ _ _ attach variables [ rs_asr ] [ Y _ CCR _ TICK _ _ _
@@ -840,8 +955,8 @@ rsASR: "%"^FPRS is rs_asr=6 & FPRS { tmp:$(SIZE) = zext(FPRS); export tmp; }
rsASR: "%"^rs_asr is rs_asr { export rs_asr; } rsASR: "%"^rs_asr is rs_asr { export rs_asr; }
#---------------RD ASR special register (STBAR instruction must be defined after this instruction) #---------------RD ASR special register (STBAR instruction must be defined after this instruction)
:rd rsASR,rd is op=0x2 & rd & op3=0x28 & rsASR & i=0 { rd = rsASR; } :rd rsASR,RD is op=0x2 & RD & op3=0x28 & rsASR & i=0 { RD = rsASR; }
:rd rsASR,rd is op=0x2 & rd & op3=0x28 & rs_asr=2 & rsASR & i=0 { packflags(rd); } # packed CCR register displayed :rd rsASR,RD is op=0x2 & RD & op3=0x28 & rs_asr=2 & rsASR & i=0 { packflags(RD); } # packed CCR register displayed
# ASR write registers (some ASR #s not permitted for wr: 1, 4, 5, 7..15, other #s handled by wr: 2, 3, 6) # ASR write registers (some ASR #s not permitted for wr: 1, 4, 5, 7..15, other #s handled by wr: 2, 3, 6)
attach variables [ rd_asr ] [ Y _ _ _ _ _ _ _ attach variables [ rd_asr ] [ Y _ _ _ _ _ _ _
@@ -850,38 +965,40 @@ attach variables [ rd_asr ] [ Y _ _ _ _ _
STICK STICK_CMPR asr26 asr27 asr28 asr29 asr30 asr31 ]; STICK STICK_CMPR asr26 asr27 asr28 asr29 asr30 asr31 ];
# ASR write registers # ASR write registers
wrCCR: "%"^CCR is rd_asr=2 & CCR { export CCR; } # packed CCR register displayed wrY: "%"^Y is rd_asr=0 & Y {export Y;}
wrASI: "%"^ASI is rd_asr=3 & ASI { export ASI; } wrCCR: "%"^CCR is rd_asr=2 & CCR { export CCR; } # packed CCR register displayed
wrASI: "%"^ASI is rd_asr=3 & ASI { export ASI; }
wrFPRS: "%"^FPRS is rd_asr=6 & FPRS { export FPRS; } wrFPRS: "%"^FPRS is rd_asr=6 & FPRS { export FPRS; }
wrASR: "%"^rd_asr is rd_asr { export rd_asr; } wrASR: "%"^rd_asr is rd_asr { export rd_asr; }
#---------------WR ASR special register (SIR instruction must be defined after this instruction) #---------------WR ASR special register (SIR instruction must be defined after this instruction)
# NOTE: the following ASR register numbers are not allowed: 1, 4, 5, 7..14 # NOTE: the following ASR register numbers are not allowed: 1, 4, 5, 7..14
:wr RS1,regorimm,wrCCR is op=0x2 & RS1 & regorimm & op3=0x30 & rd_asr=2 & wrCCR { local tmp = RS1 ^ regorimm; unpackflags(tmp); } :wr RS1,regorimm,wrCCR is op=0x2 & RS1 & regorimm & op3=0x30 & rd_asr=2 & wrCCR { local tmp = RS1 ^ regorimm; unpackflags(tmp); }
:wr RS1,regorimm,wrASI is op=0x2 & RS1 & regorimm & op3=0x30 & rd_asr=3 & wrASI { local tmp = RS1 ^ regorimm; wrASI = tmp:1; } :wr RS1,regorimm,wrASI is op=0x2 & RS1 & regorimm & op3=0x30 & rd_asr=3 & wrASI { local tmp = RS1 ^ regorimm; wrASI = tmp:1; }
:wr RS1,regorimm,wrFPRS is op=0x2 & RS1 & regorimm & op3=0x30 & rd_asr=6 & wrFPRS { local tmp = RS1 ^ regorimm; FPRS = tmp:1; } :wr RS1,regorimm,wrFPRS is op=0x2 & RS1 & regorimm & op3=0x30 & rd_asr=6 & wrFPRS { local tmp = RS1 ^ regorimm; FPRS = tmp:1; }
:wr RS1,regorimm,wrASR is op=0x2 & RS1 & regorimm & op3=0x30 & wrASR { wrASR = RS1 ^ regorimm; } :wr RS1,regorimm,wrY is op=0x2 & RS1 & regorimm & op3=0x30 & rd_asr=0 & wrY { Y = zext(RS1:4 ^ regorimm:4); }
:wr RS1,regorimm,wrASR is op=0x2 & RS1 & regorimm & op3=0x30 & wrASR { wrASR = RS1 ^ regorimm; }
#---------------MISC #---------------MISC
sethidisp: "%hi("^hi^")" is udisp22 [hi=udisp22<<10;] { export *[const]:$(SIZE) hi; } sethidisp: "%hi("^hi^")" is udisp22 [hi=udisp22<<10;] { export *[const]:$(SIZE) hi; }
:sethi sethidisp,rd is rd & op=0x0 & op2=0x4 & sethidisp { rd=sethidisp; } :sethi sethidisp,RD is RD & op=0x0 & op2=0x4 & sethidisp { RD=sethidisp; }
:popc regorimm, rd is op=0x2 & rd & op3=0x2e & rs1=0 & regorimm { rd = popc(regorimm); } :popc regorimm, RD is op=0x2 & RD & op3=0x2e & rs1=0 & regorimm { RD = popcount(regorimm); }
:save RS1,regorimm,rd is op=0x2 & rd & op3=0x3c & RS1 & regorimm { local tmp = RS1 + regorimm; save(); rd = tmp; } :save RS1,regorimm,RD is op=0x2 & RD & op3=0x3c & RS1 & regorimm { local tmp = RS1 + regorimm; save(); RD = tmp; }
:restore RS1,regorimm,rd is op=0x2 & rd & op3=0x3d & RS1 & regorimm { local tmp = RS1 + regorimm; restore(); didrestore=1; rd = tmp; } :restore RS1,regorimm,RD is op=0x2 & RD & op3=0x3d & RS1 & regorimm { local tmp = RS1 + regorimm; restore(); didrestore=1; RD = tmp; }
:restore is op=0x2 & rd=0 & op3=0x3d { restore(); didrestore=1; } :restore is op=0x2 & rd=0 & op3=0x3d { restore(); didrestore=1; }
:return retea is op=0x2 & op3=0x39 & retea { restore(); delayslot(1); didrestore=1; return [retea]; } :return retea is op=0x2 & op3=0x39 & retea { restore(); delayslot(1); didrestore=1; return [retea]; }
jmplreloff: reloc is rd [reloc=inst_start+8;] { export reloc; } jmplreloff: reloc is rd [reloc=inst_start+8;] { export reloc; }
:jmpl retea,rd is op=0x2 & rd & op3=0x38 & retea & jmplreloff { rd = inst_start; delayslot(1); goto [retea]; } :jmpl retea,RD is op=0x2 & RD & op3=0x38 & retea & jmplreloff { RD = inst_start; delayslot(1); goto [retea]; }
# special case where link register is loaded with return address # special case where link register is loaded with return address
:jmpl retea,rd is op=0x2 & rd & prd=15 & op3=0x38 & retea & jmplreloff { rd = inst_start; delayslot(1); call [retea]; } :jmpl retea,RD is op=0x2 & RD & prd=15 & op3=0x38 & retea & jmplreloff { RD = inst_start; delayslot(1); call [retea]; }
:jmpl retea is op=0x2 & rd=0 & op3=0x38 & retea { o7=inst_start; delayslot(1); goto [retea]; } :jmpl retea is op=0x2 & rd=0 & op3=0x38 & retea { o7=inst_start; delayslot(1); goto [retea]; }
:ret is op=0x2 & rd=0 & rs1=31 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; } :ret is op=0x2 & rd=0 & rs1=31 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; }
@@ -890,33 +1007,55 @@ jmplreloff: reloc is rd [reloc=inst_start+8;] { export reloc; }
casa_ea: [RS1]imm_asi is i=0 & RS1 & imm_asi { local tmp1:1 = imm_asi; local tmp = RS1+segment(tmp1); export tmp; } casa_ea: [RS1]imm_asi is i=0 & RS1 & imm_asi { local tmp1:1 = imm_asi; local tmp = RS1+segment(tmp1); export tmp; }
casa_ea: [RS1]%ASI is i=1 & RS1 & ASI { local tmp = RS1+segment(ASI); export tmp; } casa_ea: [RS1]%ASI is i=1 & RS1 & ASI { local tmp = RS1+segment(ASI); export tmp; }
:casa casa_ea,RS2,rd is op=0x3 & rd & op3=0x3c & casa_ea & RS2 { local tmp:4=rd:4; rd=zext(*:4 casa_ea); if ((RS2 & 0xFFFFFFFF)!=rd) goto <end>; *:4 casa_ea=tmp; <end> } :casa casa_ea,RS2,RD is op=0x3 & RD & op3=0x3c & casa_ea & RS2
:casxa casa_ea,RS2,rd is op=0x3 & rd & op3=0x3e & casa_ea & RS2 { local tmp=rd; rd=*:$(SIZE) casa_ea; if (RS2!=rd) goto <end>; *:$(SIZE) casa_ea=tmp; <end> } {
local tmp:4=RD:4;
RD=zext(*:4 casa_ea);
if ((RS2 & 0xFFFFFFFF)!=RD) goto <end>;
*:4 casa_ea=tmp;
<end>
}
:casxa casa_ea,RS2,RD is op=0x3 & RD & op3=0x3e & casa_ea & RS2
{
local tmp=RD;
RD=*:$(SIZE) casa_ea;
if (RS2!=RD) goto <end>;
*:$(SIZE) casa_ea=tmp;
<end>
}
:impdef1 is op=0x2 & op3=0x36 unimpl :impdef1 is op=0x2 & op3=0x36 unimpl
:impdef2 is op=0x2 & op3=0x37 unimpl :impdef2 is op=0x2 & op3=0x37 unimpl
:ldstub ea,rd is op=0x3 & rd & op3=0xd & ea { rd = zext(*:1 ea); *:1 ea = 0xFF; } :ldstub ea,RD is op=0x3 & RD & op3=0xd & ea { RD = zext(*:1 ea); *:1 ea = 0xFF; }
:ldstuba ea_alt,rd is op=0x3 & rd & op3=0x1d & ea_alt { rd = zext(*:1 ea_alt); *:1 ea_alt = 0xFF; } :ldstuba ea_alt,RD is op=0x3 & RD & op3=0x1d & ea_alt { RD = zext(*:1 ea_alt); *:1 ea_alt = 0xFF; }
:swap ea,rd is op=0x3 & rd & op3=0xF & ea { tmp:4=rd:4; rd = zext(*:4 ea); *:4 ea = tmp; } :swap ea,RD is op=0x3 & RD & op3=0xF & ea { tmp:4=RD:4; RD = zext(*:4 ea); *:4 ea = tmp; }
:swapa ea_alt,rd is op=0x3 & rd & op3=0x1F & ea_alt { tmp:4=rd:4; rd = zext(*:4 ea_alt); *:4 ea_alt = tmp; } :swapa ea_alt,RD is op=0x3 & RD & op3=0x1F & ea_alt { tmp:4=RD:4; RD = zext(*:4 ea_alt); *:4 ea_alt = tmp; }
:taddcc RS1,regorimm,rd is op=2 & rd & op3=0x20 & RS1 & regorimm {taddflags(RS1,regorimm); :taddcc RS1,regorimm,RD is op=2 & RD & op3=0x20 & RS1 & regorimm
rd = RS1 + regorimm; {
zeroflags(rd); taddflags(RS1,regorimm);
RD = RS1 + regorimm;
zeroflags(RD);
} }
:taddcctv RS1,regorimm,rd is op=2 & rd & op3=0x22 & RS1 & regorimm {taddflags(RS1,regorimm); :taddcctv RS1,regorimm,RD is op=2 & RD & op3=0x22 & RS1 & regorimm
rd = RS1 + regorimm; {
zeroflags(rd); taddflags(RS1,regorimm);
RD = RS1 + regorimm;
zeroflags(RD);
} }
:tsubcc RS1,regorimm,rd is op=2 & rd & op3=0x21 & RS1 & regorimm {taddflags(RS1,regorimm); :tsubcc RS1,regorimm,RD is op=2 & RD & op3=0x21 & RS1 & regorimm
rd = RS1 - regorimm; {
zeroflags(rd); tsubflags(RS1,regorimm);
RD = RS1 - regorimm;
zeroflags(RD);
} }
:tsubcctv RS1,regorimm,rd is op=2 & rd & op3=0x23 & RS1 & regorimm {taddflags(RS1,regorimm); :tsubcctv RS1,regorimm,RD is op=2 & RD & op3=0x23 & RS1 & regorimm
rd = RS1 - regorimm; {
zeroflags(rd); tsubflags(RS1,regorimm);
RD = RS1 - regorimm;
zeroflags(RD);
} }
tcc: icc is cc1_4=0 & cc0_4=0 & icc { export icc; } tcc: icc is cc1_4=0 & cc0_4=0 & icc { export icc; }
@@ -952,11 +1091,11 @@ tstate: "%tstate" is fcn { local tmp = zext(TL == 1)* &TSTATE1 + zext(TL == 2)*
# prs1 is same bits as rs1 # prs1 is same bits as rs1
# prd is same bits as rd # prd is same bits as rd
:rdpr prs1,rd is op=0x2 & rd & op3=0x2A & prs1 {rd = prs1; } :rdpr prs1,RD is op=0x2 & RD & op3=0x2A & prs1 {RD = prs1; }
:rdpr tpc,rd is op=0x2 & prs1 = 0 & rd & op3=0x2A & tpc { rd = *[register]:$(SIZE) tpc; } :rdpr tpc,RD is op=0x2 & prs1 = 0 & RD & op3=0x2A & tpc { RD = *[register]:$(SIZE) tpc; }
:rdpr tnpc,rd is op=0x2 & prs1 = 1 & rd & op3=0x2A & tnpc {rd = *[register]:$(SIZE) tnpc; } :rdpr tnpc,RD is op=0x2 & prs1 = 1 & RD & op3=0x2A & tnpc {RD = *[register]:$(SIZE) tnpc; }
:rdpr tt,rd is op=0x2 & prs1 = 2 & rd & op3=0x2A & tt { rd = *[register]:$(SIZE) tt; } :rdpr tt,RD is op=0x2 & prs1 = 2 & RD & op3=0x2A & tt { RD = *[register]:$(SIZE) tt; }
:rdpr tstate,rd is op=0x2 & prs1 = 3 & rd & op3=0x2A & tstate {rd = *[register]:$(SIZE) tstate;} :rdpr tstate,RD is op=0x2 & prs1 = 3 & RD & op3=0x2A & tstate {RD = *[register]:$(SIZE) tstate;}
:wrpr RS1,regorimm,prd is op=0x2 & prd & op3=0x32 & RS1 & regorimm {prd = RS1^regorimm; } :wrpr RS1,regorimm,prd is op=0x2 & prd & op3=0x32 & RS1 & regorimm {prd = RS1^regorimm; }
:wrpr RS1,regorimm,tpc is op=0x2 & prd = 0 & op3=0x32 & RS1 & regorimm & tpc { *[register]:$(SIZE) tpc = RS1^regorimm; } :wrpr RS1,regorimm,tpc is op=0x2 & prd = 0 & op3=0x32 & RS1 & regorimm & tpc { *[register]:$(SIZE) tpc = RS1^regorimm; }
@@ -978,13 +1117,13 @@ hsys_tick_cmpr: "%hstick_cmpr" is fcn { local reloc = zext(TL == 1)*&HSTICK_CM
resv30: "%resv30" is fcn { local reloc = zext(TL == 1)*&RESV30_1 + zext(TL == 2)*&RESV30_2 + zext(TL == 3)*&RESV30_3 + zext(TL ==4)*&RESV30_4; export reloc; } resv30: "%resv30" is fcn { local reloc = zext(TL == 1)*&RESV30_1 + zext(TL == 2)*&RESV30_2 + zext(TL == 3)*&RESV30_3 + zext(TL ==4)*&RESV30_4; export reloc; }
:rdhpr hpstate,rd is op=0x2 & prs1 = 0 & rd & op3=0x29 & hpstate { rd = *[register]:$(SIZE) hpstate; } :rdhpr hpstate,RD is op=0x2 & prs1 = 0 & RD & op3=0x29 & hpstate { RD = *[register]:$(SIZE) hpstate; }
:rdhpr htstate,rd is op=0x2 & prs1 = 1 & rd & op3=0x29 & htstate { rd = *[register]:$(SIZE) htstate; } :rdhpr htstate,RD is op=0x2 & prs1 = 1 & RD & op3=0x29 & htstate { RD = *[register]:$(SIZE) htstate; }
:rdhpr hintp,rd is op=0x2 & prs1 = 3 & rd & op3=0x29 & hintp { rd = *[register]:$(SIZE) hintp; } :rdhpr hintp,RD is op=0x2 & prs1 = 3 & RD & op3=0x29 & hintp { RD = *[register]:$(SIZE) hintp; }
:rdhpr htba,rd is op=0x2 & prs1 = 5 & rd & op3=0x29 & htba { rd = *[register]:$(SIZE) htba; } :rdhpr htba,RD is op=0x2 & prs1 = 5 & RD & op3=0x29 & htba { RD = *[register]:$(SIZE) htba; }
:rdhpr hver,rd is op=0x2 & prs1 = 6 & rd & op3=0x29 & hver { rd = *[register]:$(SIZE) hver; } :rdhpr hver,RD is op=0x2 & prs1 = 6 & RD & op3=0x29 & hver { RD = *[register]:$(SIZE) hver; }
:rdhpr hsys_tick_cmpr,rd is op=0x2 & prs1 = 31 & rd & op3=0x29 & hsys_tick_cmpr { rd = *[register]:$(SIZE) hsys_tick_cmpr; } :rdhpr hsys_tick_cmpr,RD is op=0x2 & prs1 = 31 & RD & op3=0x29 & hsys_tick_cmpr { RD = *[register]:$(SIZE) hsys_tick_cmpr; }
:rdhpr resv30,rd is op=0x2 & prs1 = 30 & rd & op3=0x29 & resv30 { rd = *[register]:$(SIZE) resv30; } :rdhpr resv30,RD is op=0x2 & prs1 = 30 & RD & op3=0x29 & resv30 { RD = *[register]:$(SIZE) resv30; }
:wrhpr RS1,regorimm,hpstate is op=0x2 & prd = 0 & op3=0x33 & RS1 & regorimm & hpstate { *[register]:$(SIZE) hpstate = RS1^regorimm; } :wrhpr RS1,regorimm,hpstate is op=0x2 & prd = 0 & op3=0x33 & RS1 & regorimm & hpstate { *[register]:$(SIZE) hpstate = RS1^regorimm; }
:wrhpr RS1,regorimm,htstate is op=0x2 & prd = 1 & op3=0x33 & RS1 & regorimm & htstate { *[register]:$(SIZE) htstate = RS1^regorimm; } :wrhpr RS1,regorimm,htstate is op=0x2 & prd = 1 & op3=0x33 & RS1 & regorimm & htstate { *[register]:$(SIZE) htstate = RS1^regorimm; }
@@ -1003,7 +1142,7 @@ resv30: "%resv30" is fcn { local reloc = zext(TL == 1)*&RESV30_1 + zext(TL ==
define pcodeop IllegalInstructionTrap; define pcodeop IllegalInstructionTrap;
:illtrap const22 is op = 0 & op3 = 0 & const22 { :illtrap const22 is op = 0 & op2 = 0 & const22 {
IllegalInstructionTrap(const22:4); IllegalInstructionTrap(const22:4);
tmp:$(SIZE) = 0; # trap - don't fall-thru tmp:$(SIZE) = 0; # trap - don't fall-thru
return [ tmp ]; return [ tmp ];
@@ -1214,9 +1353,9 @@ fmicc: "vc" is cond4=0xf & V { tmp:1=!V; export tmp; }
fmicc: "vs" is cond4=0x7 & V { tmp:1=V; export tmp; } fmicc: "vs" is cond4=0x7 & V { tmp:1=V; export tmp; }
# floating-point move with floating-point condition codes # floating-point move with floating-point condition codes
fmfcc: "a" is cond4=0x8 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } fmfcc: "a" is cond4=0x8 & fccn_4 { tmp:1=1:1; export tmp; }
fmfcc: "n" is cond4=0x0 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } fmfcc: "n" is cond4=0x0 & fccn_4 { tmp:1=0:1; export tmp; }
fmfcc: "u" is cond4=0x7 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } fmfcc: "u" is cond4=0x7 & fccn_4 { tmp:1=(fccn_4 == 3); export tmp; }
fmfcc: "g" is cond4=0x6 & fccn_4 { tmp:1=(fccn_4 == 2); export tmp; } fmfcc: "g" is cond4=0x6 & fccn_4 { tmp:1=(fccn_4 == 2); export tmp; }
fmfcc: "ug" is cond4=0x5 & fccn_4 { tmp:1=(fccn_4 == 2 || fccn_4 == 3); export tmp; } fmfcc: "ug" is cond4=0x5 & fccn_4 { tmp:1=(fccn_4 == 2 || fccn_4 == 3); export tmp; }
fmfcc: "l" is cond4=0x4 & fccn_4 { tmp:1=(fccn_4 == 1); export tmp; } fmfcc: "l" is cond4=0x4 & fccn_4 { tmp:1=(fccn_4 == 1); export tmp; }
@@ -1231,12 +1370,12 @@ fmfcc: "le" is cond4=0xd & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1); export
fmfcc: "ule" is cond4=0xe & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==3); export tmp; } fmfcc: "ule" is cond4=0xe & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==3); export tmp; }
fmfcc: "o" is cond4=0xf & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==2); export tmp; } fmfcc: "o" is cond4=0xf & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==2); export tmp; }
fmfcc_or_fmicc: fmfcc is bit18=0 & fmfcc { export fmfcc; } fmfcc_or_fmicc: fmfcc is bit13=0 & fmfcc { export fmfcc; }
fmfcc_or_fmicc: fmicc is bit18=1 & fmicc { export fmicc; } fmfcc_or_fmicc: fmicc is bit13=1 & fmicc { export fmicc; }
fcc_icc_xcc: "%"^fccn_4 is bit18=0 & fccn_4 { } fcc_icc_xcc: "%"^fccn_4 is bit13=0 & fccn_4 { }
fcc_icc_xcc: "%icc" is bit18=1 & opf_cc=4 { } fcc_icc_xcc: "%icc" is bit13=1 & opf_cc=4 { }
fcc_icc_xcc: "%xcc" is bit18=1 & opf_cc=6 { } fcc_icc_xcc: "%xcc" is bit13=1 & opf_cc=6 { }
:fmovs^fmfcc_or_fmicc fcc_icc_xcc,fsrs2,fsrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=1 & fsrs2 & fsrd :fmovs^fmfcc_or_fmicc fcc_icc_xcc,fsrs2,fsrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=1 & fsrs2 & fsrd
{ if !(fmfcc_or_fmicc) goto <end>; fsrd = fsrs2; <end>} { if !(fmfcc_or_fmicc) goto <end>; fsrd = fsrs2; <end>}
@@ -1245,21 +1384,26 @@ fcc_icc_xcc: "%xcc" is bit18=1 & opf_cc=6 { }
:fmovq^fmfcc_or_fmicc fcc_icc_xcc,fqrs2,fqrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=3 & fqrs2 & fqrd :fmovq^fmfcc_or_fmicc fcc_icc_xcc,fqrs2,fqrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=3 & fqrs2 & fqrd
{ if !(fmfcc_or_fmicc) goto <end>; fqrd = fqrs2; <end> } { if !(fmfcc_or_fmicc) goto <end>; fqrd = fqrs2; <end> }
:movf^fmfcc_or_fmicc fcc_icc_xcc,regorimm11,rd is op=2 & rd & op3=0x2c & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & regorimm11 #conditional integer moves with integer conditions defined in constructor :mov^m_cc
{ if !(fmfcc_or_fmicc) goto <end>; rd = regorimm11; <end> } :mov^fmfcc " %"^fccn_4,regorimm11,RD is op=2 & RD & op3=0x2c & bit18=0 & fmfcc & fccn_4 & regorimm11
{
if !(fmfcc) goto <end>;
RD = regorimm11;
<end>
}
fmovrcc: "z" is rcond3=0x1 & RS1 { tmp:1 = (RS1 f== 0); export tmp; } fmovrcc: "z" is rcond3=0x1 & RS1 { tmp:1 = (RS1 == 0); export tmp; }
fmovrcc: "lez" is rcond3=0x2 & RS1 { tmp:1 = (RS1 f<= 0); export tmp; } fmovrcc: "lez" is rcond3=0x2 & RS1 { tmp:1 = (RS1 s<= 0); export tmp; }
fmovrcc: "lz" is rcond3=0x3 & RS1 { tmp:1 = (RS1 f< 0); export tmp; } fmovrcc: "lz" is rcond3=0x3 & RS1 { tmp:1 = (RS1 s< 0); export tmp; }
fmovrcc: "nz" is rcond3=0x5 & RS1 { tmp:1 = (RS1 f!= 0); export tmp; } fmovrcc: "nz" is rcond3=0x5 & RS1 { tmp:1 = (RS1 != 0); export tmp; }
fmovrcc: "gz" is rcond3=0x6 & RS1 { tmp:1 = (RS1 f> 0); export tmp; } fmovrcc: "gz" is rcond3=0x6 & RS1 { tmp:1 = (RS1 s> 0); export tmp; }
fmovrcc: "gez" is rcond3=0x7 & RS1 { tmp:1 = (RS1 f>= 0); export tmp; } fmovrcc: "gez" is rcond3=0x7 & RS1 { tmp:1 = (RS1 s>= 0); export tmp; }
:fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x5 & fsrs2 :fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low_5_9=0x5 & fsrs2
{ if !(fmovrcc) goto <end>; fsrd = fsrs2; <end> } { if !(fmovrcc) goto <end>; fsrd = fsrs2; <end> }
:fmovrd^fmovrcc RS1,fdrs2,fdrd is op=2 & fdrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x6 & fdrs2 :fmovrd^fmovrcc RS1,fdrs2,fdrd is op=2 & fdrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low_5_9=0x6 & fdrs2
{ if !(fmovrcc) goto <end>; fdrd = fdrs2; <end> } { if !(fmovrcc) goto <end>; fdrd = fdrs2; <end> }
:fmovrq^fmovrcc RS1,fqrs2,fqrd is op=2 & fqrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x7 & fqrs2 :fmovrq^fmovrcc RS1,fqrs2,fqrd is op=2 & fqrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low_5_9=0x7 & fqrs2
{ if !(fmovrcc) goto <end>; fqrd = fqrs2; <end> } { if !(fmovrcc) goto <end>; fqrd = fqrs2; <end> }
# Include support for the VIS1 vector instructions # Include support for the VIS1 vector instructions