Merge remote-tracking branch 'origin/GT-3202_ghidorahrex_sparcv9_floating_point' into patch

This commit is contained in:
Ryan Kurtz 2019-11-06 13:05:45 -05:00
commit ec079f7844
8 changed files with 1145 additions and 915 deletions

View file

@ -9,6 +9,7 @@
<context_data>
<tracked_set space="ram">
<set name="didrestore" val="0"/>
<set name="DECOMPILE_MODE" val="1"/>
</tracked_set>
</context_data>

View file

@ -1,12 +1,14 @@
# SLA specification file for SPARC/64
define endian=big;
define alignment=4;
define space ram type=ram_space size=$(SIZE) default;
define space register type=register_space size=4;
define register offset=0 size=$(SIZE) [ g0 g1 g2 g3 g4 g5 g6 g7
define register offset=0 size=$(SIZE) [
g0 g1 g2 g3 g4 g5 g6 g7
o0 o1 o2 o3 o4 o5 sp o7
l0 l1 l2 l3 l4 l5 l6 l7
i0 i1 i2 i3 i4 i5 fp i7
@ -14,33 +16,42 @@ define register offset=0 size=$(SIZE) [ g0 g1 g2 g3 g4 g5 g6 g7
# these are save locations for implementing register windows
#
define register offset=0x500 size=$(SIZE) [ s_l0 s_l1 s_l2 s_l3 s_l4 s_l5 s_l6 s_l7
s_i0 s_i1 s_i2 s_i3 s_i4 s_i5 s_fp s_i7 ];
define register offset=0x500 size=$(SIZE) [
s_l0 s_l1 s_l2 s_l3 s_l4 s_l5 s_l6 s_l7
s_i0 s_i1 s_i2 s_i3 s_i4 s_i5 s_fp s_i7
];
define register offset=0x1000 size=$(SIZE) [ PC nPC ASR TICK Y CCR FPRS PCR PIC GSR SOFTINT_SET SOFTINT_CLR SOFTINT TICK_CMPR STICK STICK_CMPR ];
define register offset=0x1100 size=$(SIZE) [ asr7 asr8 asr9 asr10 asr11 asr12 asr13 asr14 asr15
define register offset=0x1100 size=$(SIZE) [
asr7 asr8 asr9 asr10 asr11 asr12 asr13 asr14 asr15
asr16 asr17 asr18 asr19 asr20 asr21 asr22 asr23
asr24 asr25 asr26 asr27 asr28 asr29 asr30 asr31 ];
asr24 asr25 asr26 asr27 asr28 asr29 asr30 asr31
];
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 _ _ _ _ _ _ _ fprs _ _ _ _ _ _ _ ];
define register offset=0x4000 size=$(SIZE) [ ASIext fprsext ];
define register offset=0x5000 size=1 [ fcc0 fcc1 fcc2 fcc3 ];
define register offset=0x5000 size=2 [ fsr ];
define register offset=0x5002 size=1 [ fcc0 fcc1 fcc2 fcc3 ];
define register offset=0x5010 size=1 [ didrestore ];
define register offset=0x5020 size=1 [ DECOMPILE_MODE ]; # Fake register
define register offset=0x5000 size=$(SIZE) [ TPC1 TPC2 TPC3 TPC4
define register offset=0x5000 size=$(SIZE) [
TPC1 TPC2 TPC3 TPC4
TNPC1 TNPC2 TNPC3 TNPC4
TSTATE1 TSTATE2 TSTATE3 TSTATE4
TT1 TT2 TT3 TT4
TCK TBA PSTATE TL
PIL CWP CANSAVE CANRESTORE CLEANWIN
OTHERWIN WSTATE FQ VER GL ];
OTHERWIN WSTATE FQ VER GL
];
define register offset=0x6000 size=$(SIZE) [ HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4
define register offset=0x6000 size=$(SIZE) [
HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4
HTSTATE1 HTSTATE2 HTSTATE3 HTSTATE4
RESV2_1 RESV2_2 RESV2_3 RESV2_4
HINTP1 HINTP2 HINTP3 HINTP4
@ -52,20 +63,20 @@ define register offset=0x6000 size=$(SIZE) [ HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4
HSTICK_CMPR1 HSTICK_CMPR2 HSTICK_CMPR3 HSTICK_CMPR4
];
# A window is 24 registers (96 or 192 bytes), must processors have 7 or 8. (g0->g7,o0->o7,l0->o7,i0->i7)
# A window is 24 registers (96 or 192 bytes), most processors have 7 or 8. (g0->g7,o0->o7,l0->o7,i0->i7)
# When the window is overflowed the data must be purged to some backup memory, via user
# suppied function attached to a signal handler.
# supplied function attached to a signal handler.
# When the window is underflowed the data must be read from some backup memory, via user
# suppied function attached to a signal handler.
# supplied function attached to a signal handler.
# There are 2 basic strategies we figured for this.
# One, create a bank of register space and read and write to it in a way that simulates
# how the sparc would really work, but the symboic names become indexes.
# how the sparc would really work, but the symbolic names become indexes.
# Two, save and restore logic does all the work.
# window index is ((CWP+1)%NWINDOWS)
# CWP is an index from 0 to N of the wondows.
# Size of CWP is implimination depedent (must be > 5 bits).
# CWP is an index from 0 to N of the windows.
# Size of CWP is implementation dependent (must be > 5 bits).
# inputs i0 i1 i2 i3 i4 i5 fp i7
# locals l0 l1 l2 l3 l4 l5 l6 l7
@ -80,36 +91,51 @@ define register offset=0x7000 size=$(SIZE) [
w010 w011 w012 w013 w014 w015 w016 w017
w020 w021 w022 w023 w024 w025 w026 w027
w030 w031 w032 w033 w034 w035 w036 w037
w110 w111 w112 w113 w114 w115 w116 w117
w120 w121 w122 w123 w124 w125 w126 w127
w130 w131 w132 w133 w134 w135 w136 w137
w210 w211 w212 w213 w214 w215 w216 w217
w220 w221 w222 w223 w224 w225 w226 w227
w230 w231 w232 w233 w234 w235 w236 w237
w310 w311 w312 w313 w314 w315 w316 w317
w320 w321 w322 w323 w324 w325 w326 w327
w330 w331 w332 w333 w334 w335 w336 w337
w410 w411 w412 w413 w414 w415 w416 w417
w420 w421 w422 w423 w424 w425 w426 w427
w430 w431 w432 w433 w434 w435 w436 w437
w510 w511 w512 w513 w514 w515 w516 w517
w520 w521 w522 w523 w524 w525 w526 w527
w530 w531 w532 w533 w534 w535 w536 w537
w610 w611 w612 w613 w614 w615 w616 w617
w620 w621 w622 w623 w624 w625 w626 w627
w630 w631 w632 w633 w634 w635 w636 w637
w710 w711 w712 w713 w714 w715 w716 w717
w720 w721 w722 w723 w724 w725 w726 w727
w730 w731 w732 w733 w734 w735 w736 w737
];
# Floating-point registers
define register offset=0x2000 size=4 [
fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7
fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15
fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23
fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31
];
define register offset=0x2000 size=8 [
fd0 fd2 fd4 fd6 fd8 fd10 fd12 fd14
fd16 fd18 fd20 fd22 fd24 fd26 fd28 fd30
fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46
fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62
];
define register offset=0x2000 size=16 [
fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28
fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60
];
define pcodeop segment;
define pcodeop popc;
define pcodeop sw_trap;
@ -204,6 +230,7 @@ attach variables [ rd_d ] [
l0_1 _ l2_3 _ l4_5 _ l6_7 _
i0_1 _ i2_3 _ i4_5 _ fp_7 _
];
@endif
attach variables [ fccn fccn2 fccn_4 ] [ fcc0 fcc1 fcc2 fcc3 ];
@ -217,9 +244,7 @@ attach variables [ rs1_3 ] [ Y _ CCR _ TICK PC _
# "%o0" "%o1" "%o2" "%o3" "%o4" "%o5" "%sp" "%o7"
# "%l0" "%l1" "%l2" "%l3" "%l4" "%l5" "%l6" "%l7"
# "%i0" "%i1" "%i2" "%i3" "%i4" "%i5" "%fp" "%i7" ];
# Window register table accessors ===================================
@define NUMREGWINS 8
@define REGWINSZ 16
@define LOCALOFF 8
@ -229,27 +254,28 @@ attach variables [ rs1_3 ] [ Y _ CCR _ TICK PC _
# CWP++
macro save() {
@if SIZE=="4"
# # Save inputs
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+0)*$(SIZE)) = i0;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+1)*$(SIZE)) = i1;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+2)*$(SIZE)) = i2;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+3)*$(SIZE)) = i3;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+4)*$(SIZE)) = i4;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+5)*$(SIZE)) = i5;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+6)*$(SIZE)) = fp;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+7)*$(SIZE)) = i7;
#
# # Save local
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)) = l0;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)) = l1;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)) = l3;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)) = l3;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)) = l4;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)) = l5;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)) = l6;
# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+7+$(LOCALOFF))*$(SIZE)) = l7;
if (DECOMPILE_MODE) goto <skip_rotate>;
# Save inputs
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0)*$(SIZE)) = i0;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1)*$(SIZE)) = i1;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2)*$(SIZE)) = i2;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3)*$(SIZE)) = i3;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4)*$(SIZE)) = i4;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5)*$(SIZE)) = i5;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6)*$(SIZE)) = fp;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7)*$(SIZE)) = i7;
# Save local
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)) = l0;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)) = l1;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)) = l3;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)) = l3;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)) = l4;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)) = l5;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)) = l6;
*[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7+$(LOCALOFF))*$(SIZE)) = l7;
<skip_rotate>
# what was outputs become inputs
i0 = o0;
i1 = o1;
@ -270,44 +296,6 @@ macro save() {
l6 = 0;
l7 = 0;
# # zero out outputs
# o0 = 0;
# o1 = 0;
# o2 = 0;
# o3 = 0;
# o4 = 0;
# o5 = 0;
# sp = 0;
# o7 = 0;
@else
i0 = o0;
i1 = o1;
i2 = o2;
i3 = o3;
i4 = o4;
i5 = o5;
fp = sp;
i7 = o7;
# o0 = 0;
# o1 = 0;
# o2 = 0;
# o3 = 0;
# o4 = 0;
# o5 = 0;
# sp = 0;
# o7 = 0;
l0 = 0;
l1 = 0;
l2 = 0;
l3 = 0;
l4 = 0;
l5 = 0;
l6 = 0;
l7 = 0;
@endif
CWP = CWP + 1;
}
@ -316,7 +304,6 @@ macro save() {
macro restore() {
CWP = CWP - 1;
@if SIZE=="4"
# inputs once again become outputs
o0 = i0; # API return value
o1 = i1;
@ -327,35 +314,27 @@ macro restore() {
sp = fp;
o7 = i7; # address of CALLer address
# # restore original inputs
# i0 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+0)*$(SIZE)));
# i1 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+1)*$(SIZE)));
# i2 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+2)*$(SIZE)));
# i3 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+3)*$(SIZE)));
# i4 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+4)*$(SIZE)));
# i5 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+5)*$(SIZE)));
# fp = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+6)*$(SIZE)));
# i7 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+7)*$(SIZE))); # address of CALLer address
#
# # restore original locals
# l0 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)));
# l1 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)));
# l2 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)));
# l3 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)));
# l4 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)));
# l5 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)));
# l6 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)));
# l7 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)));
@else
o0 = i0;
o1 = i1;
o2 = i2;
o3 = i3;
o4 = i4;
o5 = i5;
sp = fp;
o7 = i7;
@endif
if (DECOMPILE_MODE) goto <skip_rotate>;
# restore original inputs
i0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0)*$(SIZE)));
i1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1)*$(SIZE)));
i2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2)*$(SIZE)));
i3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3)*$(SIZE)));
i4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4)*$(SIZE)));
i5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5)*$(SIZE)));
fp = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6)*$(SIZE)));
i7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+7)*$(SIZE))); # address of CALLer address
# restore original locals
l0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)));
l1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)));
l2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)));
l3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)));
l4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)));
l5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)));
l6 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)));
l7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)));
<skip_rotate>
}
RS1: rs1 is rs1 & rs1_zero=0 { export 0:$(SIZE); }
@ -461,54 +440,59 @@ macro unpackflags(ccr) {
i_cf = (ccr & 0x1)!=0;
}
# ---------------
: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);
rd = RS1 + regorimm;
zeroflags(rd); }
zeroflags(rd);
}
: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 {addflags(RS1,regorimm);
rd = RS1 + regorimm + zext(i_cf);
zeroflags(rd); }
zeroflags(rd);
}
#-----------------------
: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();
rd = RS1 & regorimm;
zeroflags(rd); }
zeroflags(rd);
}
: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();
rd = RS1 & ~regorimm;
zeroflags(rd); }
zeroflags(rd);
}
: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();
rd = RS1 | regorimm;
zeroflags(rd); }
zeroflags(rd);
}
: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();
rd = RS1 | ~regorimm;
zeroflags(rd); }
zeroflags(rd);
}
: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();
rd = RS1 ^ regorimm;
zeroflags(rd); }
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();
rd = RS1 ^ ~regorimm;
zeroflags(rd); }
zeroflags(rd);
}
# ---------------
:ldsb ea,rd is op=3 & rd & op3=0x09 & ea { rd = sext(*:1 ea); }
@ -522,7 +506,8 @@ macro unpackflags(ccr) {
@if SIZE=="8"
:ldd ea,rd is op=3 & rd & op3=0x03 & ea { rd = *:$(SIZE) ea; }
@else
:ldd ea,rd is op=3 & rd & rd_d & op3=0x03 & ea { tmp:8 = *:8 ea; rd_d = tmp; }
:ldd ea,rd is op=3 & rd & rd_d & op3=0x03 & ea { rd_d = *:8 ea; }
@endif
:ldsba ea_alt,rd is op=3 & rd & op3=0x19 & ea_alt { rd = sext(*:1 ea_alt); }
@ -544,14 +529,14 @@ macro unpackflags(ccr) {
:stx RD,ea is op=3 & RD & op3=0x0e & ea { *ea = RD; }
:std RD,ea is op=3 & RD & op3=0x07 & ea { *ea = RD; }
@else
# size = 4, but this extended store insn needs to write 8 bytes
:stx RD,ea is op=3 & RD & rd_d & op3=0x0e & ea { *ea = rd_d:8; }
:clrx ea is op=3 & rd=0 & op3=0x0e & ea { *ea = 0:8; }
:std RD,ea is op=3 & RD & rd_d & op3=0x07 & ea { *ea = rd_d:8; }
:clrd ea is op=3 & rd=0 & op3=0x07 & ea { *ea = 0:8; }
# size = 4, but this extended store instruction needs to write 8 bytes
:stx RD,ea is op=3 & RD & rd_d & op3=0x0e & ea { *ea = rd_d; }
:std RD,ea is op=3 & RD & rd_d & op3=0x07 & ea { *ea = rd_d; }
@endif
:clrx ea is op=3 & rd=0 & op3=0x0e & ea { *ea = 0:8; }
:clrd ea is op=3 & rd=0 & op3=0x07 & ea { *ea = 0:8; }
:stba RD,ea_alt is op=3 & RD & op3=0x15 & ea_alt { *ea_alt = RD:1; }
:stha RD,ea_alt is op=3 & RD & op3=0x16 & ea_alt { *ea_alt = RD:2; }
:stwa RD,ea_alt is op=3 & RD & op3=0x14 & ea_alt { *ea_alt = RD:4; }
@ -563,13 +548,15 @@ macro unpackflags(ccr) {
:subcc RS1,regorimm,rd is op=2 & rd & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm);
rd = RS1 - regorimm;
zeroflags(rd); }
zeroflags(rd);
}
:subc RS1,regorimm,rd is op=2 & rd & op3=0xc & RS1 & regorimm {rd = RS1 - regorimm - zext(i_cf);}
:subccc RS1,regorimm,rd is op=2 & rd & op3=0x1c & RS1 & regorimm {subflags(RS1,regorimm);
rd = RS1 - regorimm - zext(i_cf);
zeroflags(rd); }
zeroflags(rd);
}
# ---------------
@ -579,7 +566,8 @@ macro unpackflags(ccr) {
:cmp RS1,regorimm is op=0x2 & rd=0x0 & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm);
local tmp = RS1 - regorimm;
zeroflags(tmp); }
zeroflags(tmp);
}
# ---------------MOVES
@ -594,18 +582,19 @@ RCOND: "lz" is rcond3=3 & RS1 { tmp:1 = (RS1 s< 0); export tmp; }
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: "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 {
if !RCOND goto <movrend>;
rd = regorimm10;
<movrend>
}
#:movrz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=1 & regorimm10 { if (RS1 == 0) goto inst_next; rd = regorimm10; }
#:movrlez RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=2 & regorimm10 { if (RS1 s<= 0) goto inst_next; rd = regorimm10; }
#:movrlz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=3 & regorimm10 { if (RS1 s< 0) goto inst_next; rd = regorimm10; }
#:movrnz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=5 & regorimm10 { if (RS1 != 0) goto inst_next; rd = regorimm10; }
#:movrgz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=6 & regorimm10 { if (RS1 s> 0) goto inst_next; rd = regorimm10; }
#:movrgez RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=7 & regorimm10 { if (RS1 s>= 0) goto inst_next; rd = regorimm10; }
m_icc: "a" is cond4=0x8 { tmp:1=1; export tmp; }
m_icc: "n" is cond4=0x0 { tmp:1=0; export tmp; }
m_icc: "ne" is cond4=0x9 { tmp:1=!i_zf; export tmp; }
@ -653,7 +642,6 @@ MICC: "%xcc" is cc2_4=1 &cc1_4=1 { }
}
# ---------------BRANCHES
icc: "a" is cond=0x8 { tmp:1=1; export tmp; }
icc: "ne" is cond=0x9 { tmp:1=!i_zf; export tmp; }
icc: "e" is cond=0x1 { tmp:1=i_zf; export tmp; }
@ -736,19 +724,15 @@ skip: reloc is epsilon [reloc=inst_start+8;] { export *:$(SIZE) reloc; }
#:br^cc^predict reloff64 is op=0x0 & a=0x0 & op2=0x3 & cc & reloff64 & predict { delayslot(1); if (cc) goto reloff64; }
#:br^cc^",a"^predict reloff64 is op=0x0 & a=0x1 & op2=0x3 & cc & reloff64 & predict { if (!cc) goto inst_next; delayslot(1); goto reloff64; }
#---------------CALL
callreloff: reloc is disp30 [reloc=inst_start+4*disp30;] { export *:$(SIZE) reloc; }
:call callreloff is op=0x1 & callreloff
{
:call callreloff is op=0x1 & callreloff {
o7=inst_start; didrestore=0; delayslot(1); call callreloff; if (didrestore==0) goto inst_next; return [o7];
}
# changing to jump for PIC call if destination is right below this one.
:call callreloff is op=0x1 & disp30=2 & callreloff
{
:call callreloff is op=0x1 & disp30=2 & callreloff {
o7=inst_start; delayslot(1); goto callreloff;
}
@ -761,26 +745,27 @@ callreloff: reloc is disp30 [reloc=inst_start+4*disp30;] {export *:$(SIZE) reloc
:udivx RS1,regorimm,rd is op=2 & rd & op3=0x0d & RS1 & regorimm {rd = RS1 / regorimm;}
#----------------MULTIPLY 32 bit
@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;}
:smul RS1,regorimm,rd is op=2 & rd & op3=0x0b & RS1 & regorimm {rd = zext(RS1:4) * zext(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();}
: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();}
@else
# size = 4
: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: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 {
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: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();}
: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
#----------------MULTIPLY Step
@ -846,7 +831,6 @@ callreloff: reloc is disp30 [reloc=inst_start+4*disp30;] {export *:$(SIZE) reloc
: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; }
rreg: "%ASI" is rs1_3=3 & i=0 { tmp:$(SIZE) = zext(ASI); export tmp; }
rreg: "%fprs" is rs1_3=6 & i=0 { tmp:$(SIZE) = zext(fprs); export tmp; }
rreg: "%ccr" is rs1_3=2 & i=0 { tmp:$(SIZE) = zext(CCR); export tmp; }
@ -854,12 +838,13 @@ rreg: PC is rs1_3=5 & PC & i=0 { export inst_start; }
rreg: rs1_3 is rs1_3 & i=0 { export rs1_3; }
#---------------RD special register
:rd rreg,rd is op=0x2 & rd & op3=0x28 & rreg & i=0 { rd = rreg; }
:rd rreg,rd is op=0x2 & rd & op3=0x28 & rs1_3=2 & rreg & i=0 { packflags(rd); }
wrASI: "%ASI" is rd=3 { }
wrFPRS: "%fprs" is rd=6 { }
wrCCR: "%ccr" is rd=2 { }
#---------------WR special register
@ -869,7 +854,6 @@ wrCCR: "%ccr" is rd=2 {}
:wr regorimm,rd is op=0x2 & regorimm & op3=0x30 & rd { rd = regorimm; }
#---------------MISC
sethidisp: "%hi("^hi^")" is udisp22 [hi=udisp22<<10;] { export *[const]:$(SIZE) hi; }
:sethi sethidisp,rd is rd & op=0x0 & op2=0x4 & sethidisp { rd=sethidisp; }
@ -894,12 +878,11 @@ jmplreloff: reloc is rd [reloc=inst_start+8;] { export reloc; }
:ret is op=0x2 & rd=0 & rs1=31 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; }
:retl is op=0x2 & rd=0 & rs1=15 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; }
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 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 inst_next; *:4 casa_ea=tmp; }
: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 inst_next; *:$(SIZE) casa_ea=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> }
: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
:impdef2 is op=0x2 & op3=0x37 unimpl
@ -912,26 +895,34 @@ casa_ea: [RS1]%ASI is i=1 & RS1 & ASI { local tmp = RS1+segment(ASI); exp
:taddcc RS1,regorimm,rd is op=2 & rd & op3=0x20 & RS1 & regorimm {taddflags(RS1,regorimm);
rd = RS1 + regorimm;
zeroflags(rd); }
zeroflags(rd);
}
:taddcctv RS1,regorimm,rd is op=2 & rd & op3=0x22 & RS1 & regorimm {taddflags(RS1,regorimm);
rd = RS1 + regorimm;
zeroflags(rd); }
zeroflags(rd);
}
:tsubcc RS1,regorimm,rd is op=2 & rd & op3=0x21 & RS1 & regorimm {taddflags(RS1,regorimm);
rd = RS1 - regorimm;
zeroflags(rd); }
zeroflags(rd);
}
:tsubcctv RS1,regorimm,rd is op=2 & rd & op3=0x23 & RS1 & regorimm {taddflags(RS1,regorimm);
rd = RS1 - regorimm;
zeroflags(rd); }
zeroflags(rd);
}
tcc: icc is cc1_4=0 & cc0_4=0 & icc { export icc; }
tcc: xcc is cc1_4=1 & cc0_4=0 & xcc { export xcc; }
TICC: "%icc" is cc1_4=0 &cc0_4=0 { }
TICC: "%xcc" is cc1_4=1 &cc0_4=0 { }
trap: RS1+RS2 is i=0 & RS1 & RS2 { local tmp = ((RS1 + RS2) & 0x7F); export tmp; }
trap: RS1+swtrap is i=1 & RS1 & swtrap { local tmp = ((RS1 + swtrap) & 0x7F); export tmp; }
:t^tcc TICC, trap is op=0x2 & op3=0x3a & tcc & TICC & trap { sw_trap(trap); }
membar_mask: is cmask & mmask { tmp:1 = (cmask << 4) | mmask; export tmp; }
:membar membar_mask is op=0x2 & rd=0 & op3=0x28 & rs1=0xF & i=1 & membar_mask {}
:stbar is op=0x2 & rd=0 & op3=0x28 & rs1=0xF & i=0 {}
@ -943,8 +934,11 @@ attach variables [ prs1 prd ] [ TPC1 TNPC1 TSTATE1 TT1 TCK TBA PSTATE TL
GL _ _ _ _ _ _ _ _ _ _ _ _ _ _ VER ];
tnpc: "%tnpc" is fcn { local reloc = zext(TL == 1)*&TNPC1 + zext(TL == 2)*&TNPC2 + zext(TL == 3)*&TNPC3 + zext(TL ==4)*&TNPC4; export reloc; }
tpc: "%tpc" is fcn { local reloc = zext(TL == 1)*&TPC1 + zext(TL == 2)*&TPC2 + zext(TL == 3)*&TPC3 + zext(TL ==4)*&TPC4; export reloc; }
tt: "%tt" is fcn { local tmp = zext(TL == 1)* &TT1 + zext(TL == 2)*&TT2 + zext(TL == 3)*&TT3 + zext(TL ==4)*&TT4; export tmp; }
tstate: "%tstate" is fcn { local tmp = zext(TL == 1)* &TSTATE1 + zext(TL == 2)* &TSTATE2 + zext(TL == 3)* &TSTATE3 + zext(TL==4)* &TSTATE4; export tmp; }
# prs1 is same bits as rs1
@ -961,13 +955,16 @@ tstate: "%tstate" is fcn {local tmp = zext(TL == 1)* &TSTATE1 + zext(TL == 2)* &
:wrpr RS1,regorimm,tstate is op=0x2 & prd = 2 & op3=0x32 & RS1 & regorimm & tstate { *[register]:$(SIZE) tstate = RS1^regorimm; }
:wrpr RS1,regorimm,tt is op=0x2 & prd = 3 & op3=0x32 & RS1 & regorimm & tt { *[register]:$(SIZE) tt = RS1^regorimm; }
hpstate: "%hpstate" is fcn { local reloc = zext(TL == 1)*&HPSTATE1 + zext(TL == 2)*&HPSTATE2 + zext(TL == 3)*&HPSTATE3 + zext(TL ==4)*&HPSTATE4; export reloc; }
htstate: "%htstate" is fcn { local reloc = zext(TL == 1)*&HTSTATE1 + zext(TL == 2)*&HTSTATE2 + zext(TL == 3)*&HTSTATE3 + zext(TL ==4)*&HTSTATE4; export reloc; }
hintp: "%hintp" is fcn { local reloc = zext(TL == 1)*&HINTP1 + zext(TL == 2)*&HINTP2 + zext(TL == 3)*&HINTP3 + zext(TL ==4)*&HINTP4; export reloc; }
htba: "%htba" is fcn { local reloc = zext(TL == 1)*&HTBA1 + zext(TL == 2)*&HTBA2 + zext(TL == 3)*&HTBA3 + zext(TL ==4)*&HTBA4; export reloc; }
hver: "%hver" is fcn { local reloc = zext(TL == 1)*&HVER1 + zext(TL == 2)*&HVER2 + zext(TL == 3)*&HVER3 + zext(TL ==4)*&HVER4; export reloc; }
hsys_tick_cmpr: "%hstick_cmpr" is fcn { local reloc = zext(TL == 1)*&HSTICK_CMPR1 + zext(TL == 2)*&HSTICK_CMPR2 + zext(TL == 3)*&HSTICK_CMPR3 + zext(TL ==4)*&HSTICK_CMPR4; 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; }
@ -1008,22 +1005,6 @@ define pcodeop IllegalInstructionTrap;
:restored is op = 2 & fcn=1 & op3 = 0x31 {}
:saved is op = 2 & fcn = 0 & op3 = 0x31 {}
#---- TO DO: floating point
define register offset=0x2000 size=4 [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7
fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15
fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23
fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31 ];
define register offset=0x2000 size=8 [fd0 fd2 fd4 fd6 fd8 fd10 fd12 fd14
fd16 fd18 fd20 fd22 fd24 fd26 fd28 fd30
fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46
fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62 ];
define register offset=0x2000 size=16 [fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28
fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60 ];
attach variables [fsrd fsrs1 fsrs2 ] [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7
fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15
fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23
@ -1036,52 +1017,6 @@ attach variables [fdrd fdrs1 fdrs2 ] [ fd0 fd32 fd2 fd34 fd4 fd36 fd6 fd38
attach variables [fqrd fqrs1 fqrs2 ] [ fq0 _ fq32 _ fq4 _ fq36 _ fq8 _ fq40 _ fq12 _ fq44
_ fq16 _ fq48 _ fq20 _ fq52 _ fq24 _ fq56 _ fq28 _ fq60 _];
define pcodeop fabss;
define pcodeop fabsd;
define pcodeop fabsq;
define pcodeop fadds;
define pcodeop faddd;
define pcodeop faddq;
define pcodeop fdivs;
define pcodeop fdivd;
define pcodeop fdivq;
define pcodeop fdmulq;
define pcodeop fitos;
define pcodeop fitod;
define pcodeop fitoq;
define pcodeop fmovs;
define pcodeop fmovd;
define pcodeop fmovq;
define pcodeop fmuls;
define pcodeop fmuld;
define pcodeop fmulq;
define pcodeop fnegs;
define pcodeop fnegd;
define pcodeop fnegq;
define pcodeop fsmuld;
define pcodeop fsubs;
define pcodeop fsubd;
define pcodeop fsubq;
define pcodeop fxtos;
define pcodeop fxtod;
define pcodeop fxtoq;
define pcodeop fstoi;
define pcodeop fdtoi;
define pcodeop fqtoi;
define pcodeop fstox;
define pcodeop fdtox;
define pcodeop fqtox;
define pcodeop fstod;
define pcodeop fstoq;
define pcodeop fdtos;
define pcodeop fdtoq;
define pcodeop fqtos;
define pcodeop fqtod;
define pcodeop fsqrts;
define pcodeop fsqrtd;
define pcodeop fsqrtq;
define pcodeop ld;
define pcodeop ldd;
@ -1104,77 +1039,98 @@ define pcodeop sta;
define pcodeop stda;
define pcodeop stqa;
:fabss fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x9 & fsrs2 { fsrd = fabss(fsrs2); }
:fabsd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xa & fdrs2 { fdrd = fabss(fdrs2); }
:fabsq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xb & fqrs2 { fqrd = fabss(fqrs2); }
:fadds fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x41 & fsrs2 { fsrd = fadds(fsrs1, fsrs2); }
:faddd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x42 & fdrs2 { fdrd = faddd(fsrs1, fdrs2); }
:faddq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x43 & fqrs2 { fqrd = faddq(fsrs1, fqrs2); }
:fdivs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x4d & fsrs2 { fsrd = fdivs(fsrs1, fsrs2); }
:fdivd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x4e & fdrs2 { fdrd = fdivd(fsrs1, fdrs2); }
:fdivq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x4f & fqrs2 { fqrd = fdivq(fsrs1, fqrs2); }
:fdmulq fdrs1,fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fdrs1 & opf=0x6e & fdrs2 { fqrd = fdmulq(fdrs1, fdrs2); }
:fitos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc4 & fsrs2 { fsrd = fitos(fsrs2); }
:fitod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc8 & fdrs2 { fdrd = fitod(fdrs2); }
:fitoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcc & fqrs2 { fqrd = fitoq(fqrs2); }
:fmovs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x1 & fsrs2 { fsrd = fmovs(fsrs2); }
:fmovd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2 & fdrs2 { fdrd = fmovd(fdrs2); }
:fmovq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x3 & fqrs2 { fqrd = fmovq(fqrs2); }
:fmuls fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x49 & fsrs2 { fsrd = fmuls(fsrs1, fsrs2); }
:fmuld fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x4a & fdrs2 { fdrd = fmuld(fsrs1, fdrs2); }
:fmulq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x4b & fqrs2 { fqrd = fmulq(fsrs1, fqrs2); }
:fnegs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x5 & fsrs2 { fsrd = fnegs(fsrs2); }
:fnegd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x6 & fdrs2 { fdrd = fnegd(fdrs2); }
:fnegq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x7 & fqrs2 { fqrd = fnegq(fqrs2); }
:fsmuld fsrs1,fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x69 & fsrs2 { fdrd = fsmuld(fsrs1, fsrs2); }
:fsubs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x45 & fsrs2 { fsrd = fsubs(fsrs1, fsrs2); }
:fsubd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x46 & fdrs2 { fdrd = fsubd(fsrs1, fdrs2); }
:fsubq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x47 & fqrs2 { fqrd = fsubq(fsrs1, fqrs2); }
:fxtos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x84 & fsrs2 { fsrd = fxtos(fsrs2); }
:fxtod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x88 & fdrs2 { fdrd = fxtod(fdrs2); }
:fxtoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x8c & fqrs2 { fqrd = fxtoq(fqrs2); }
:fabss fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x9 & fsrs2 { fsrd = abs(fsrs2); }
:fabsd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xa & fdrs2 { fdrd = abs(fdrs2); }
:fabsq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xb & fqrs2 { fqrd = abs(fqrs2); }
:fstoi fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xd1 & fsrs2 { fsrd = fstoi(fsrs2); }
:fdtoi fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xd2 & fdrs2 { fdrd = fdtoi(fdrs2); }
:fqtoi fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xd3 & fqrs2 { fqrd = fqtoi(fqrs2); }
:fstox fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x81 & fsrs2 { fsrd = fstox(fsrs2); }
:fdtox fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x82 & fdrs2 { fdrd = fdtox(fdrs2); }
:fqtox fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x83 & fqrs2 { fqrd = fqtox(fqrs2); }
:fstod fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc9 & fsrs2 { fsrd = fstod(fsrs2); }
:fstoq fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xcd & fdrs2 { fdrd = fstoq(fdrs2); }
:fdtos fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xc6 & fqrs2 { fqrd = fdtos(fqrs2); }
:fdtoq fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xce & fsrs2 { fsrd = fdtoq(fsrs2); }
:fqtos fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc7 & fdrs2 { fdrd = fqtos(fdrs2); }
:fqtod fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcb & fqrs2 { fqrd = fqtod(fqrs2); }
:fadds fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x41 & fsrs2 { fsrd = fsrs1 f+ fsrs2; }
:faddd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x42 & fdrs2 { fdrd = fdrs1 f+ fdrs2; }
:faddq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x43 & fqrs2 { fqrd = fqrs1 f+ fqrs2; }
:fsqrts fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x29 & fsrs2 { fsrd = fsqrts(fsrs2); }
:fsqrtd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2a & fdrs2 { fdrd = fsqrtd(fdrs2); }
:fsqrtq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x2b & fqrs2 { fqrd = fsqrtq(fqrs2); }
:fdivs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x4d & fsrs2 { fsrd = fsrs1 f/ fsrs2; }
:fdivd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4e & fdrs2 { fdrd = fdrs1 f/ fdrs2; }
:fdivq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4f & fqrs2 { fqrd = fqrs1 f/ fqrs2; }
:ld ea,fsrd is op=3 & fsrd & op3=0x20 & ea { fsrd = ld(ea); }
:ldd ea,fdrd is op=3 & fdrd & op3=0x23 & ea { fdrd = ldd(ea); }
:ldq ea,fqrd is op=3 & fqrd & op3=0x22 & ea { fqrd = ldq(ea); }
:ld ea,"%fsr" is op=3 & op3=0x21 & rd=0 & ea { ld_fsr(ea); }
:ldx ea,"%fsr" is op=3 & op3=0x21 & rd=1 & ea { ldx_fsr(ea); }
:lda ea_alt,fsrd is op=3 & fsrd & op3=0x30 & ea_alt { fsrd = lda(ea_alt); }
:ldda ea_alt,fdrd is op=3 & fdrd & op3=0x33 & ea_alt { fdrd = ldda(ea_alt); }
:ldqa ea_alt,fqrd is op=3 & fqrd & op3=0x32 & ea_alt { fqrd = ldqa(ea_alt); }
:fdmulq fdrs1,fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fdrs1 & opf=0x6e & fdrs2 {
tmp1:16 = float2float(fdrs1);
tmp2:16 = float2float(fdrs2);
fqrd = tmp1 f* tmp2;
}
:fsmuld fsrs1,fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x69 & fsrs2 {
tmp1:8 = float2float(fsrs1);
tmp2:8 = float2float(fsrs2);
fdrd = tmp1 f* tmp2;
}
:st fsrd,ea is op=3 & fsrd & op3=0x24 & ea { ea = st(fsrd); }
:std fdrd,ea is op=3 & fdrd & op3=0x27 & ea { ea = std(fdrd); }
:stq fqrd,ea is op=3 & fqrd & op3=0x26 & ea { ea = stq(fqrd); }
:st "%fsr",ea is op=3 & op3=0x25 & rd=0 & ea { ea = st_fsr(); }
:stx "%fsr",ea is op=3 & op3=0x25 & rd=1 & ea { ea = stx_fsr(); }
:fitos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc4 & fsrs2 { fsrd = int2float(fsrs2); }
:fitod fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc8 & fsrs2 { fdrd = int2float(fsrs2); }
:fitoq fsrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcc & fsrs2 { fqrd = int2float(fsrs2); }
:sta fsrd,ea_alt is op=3 & fsrd & op3=0x34 & ea_alt { ea_alt = sta(fsrd); }
:stda fdrd,ea_alt is op=3 & fdrd & op3=0x37 & ea_alt { ea_alt = stda(fdrd); }
:stqa fqrd,ea_alt is op=3 & fqrd & op3=0x36 & ea_alt { ea_alt = stqa(fqrd); }
:fmovs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x1 & fsrs2 { fsrd = fsrs2; }
:fmovd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2 & fdrs2 { fdrd = fdrs2; }
:fmovq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x3 & fqrs2 { fqrd = fqrs2; }
:fmuls fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x49 & fsrs2 { fsrd = fsrs1 f* fsrs2; }
:fmuld fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4a & fdrs2 { fdrd = fdrs1 f* fdrs2; }
:fmulq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4b & fqrs2 { fqrd = fqrs1 f* fqrs2; }
:fnegs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x5 & fsrs2 { fsrd = f- fsrs2; }
:fnegd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x6 & fdrs2 { fdrd = f- fdrs2; }
:fnegq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x7 & fqrs2 { fqrd = f- fqrs2; }
:fsubs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x45 & fsrs2 { fsrd = fsrs1 f- fsrs2; }
:fsubd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x46 & fdrs2 { fdrd = fdrs1 f- fdrs2; }
:fsubq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x47 & fqrs2 { fqrd = fqrs1 f- fqrs2; }
:fxtos fdrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x84 & fdrs2 { fsrd = int2float(fdrs2); }
:fxtod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x88 & fdrs2 { fdrd = int2float(fdrs2); }
:fxtoq fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x8c & fdrs2 { fqrd = int2float(fdrs2); }
:fstoi fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xd1 & fsrs2 { fsrd = trunc(fsrs2); }
:fdtoi fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xd2 & fdrs2 { fdrd = trunc(fdrs2); }
:fqtoi fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xd3 & fqrs2 { fqrd = trunc(fqrs2); }
:fstox fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x81 & fsrs2 { fsrd = trunc(fsrs2); }
:fdtox fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x82 & fdrs2 { fdrd = trunc(fdrs2); }
:fqtox fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x83 & fqrs2 { fqrd = trunc(fqrs2); }
:fstod fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc9 & fsrs2 { fdrd = float2float(fsrs2); }
:fstoq fsrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcd & fsrs2 { fqrd = float2float(fsrs2); }
:fdtos fdrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc6 & fdrs2 { fsrd = float2float(fdrs2); }
:fdtoq fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xce & fdrs2 { fqrd = float2float(fdrs2); }
:fqtos fdrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc7 & fdrs2 { fsrd = float2float(fdrs2); }
:fqtod fqrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xcb & fqrs2 { fdrd = float2float(fqrs2); }
:fsqrts fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x29 & fsrs2 { fsrd = sqrt(fsrs2); }
:fsqrtd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2a & fdrs2 { fdrd = sqrt(fdrs2); }
:fsqrtq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x2b & fqrs2 { fqrd = sqrt(fqrs2); }
:ld ea,fsrd is op=3 & fsrd & op3=0x20 & ea { fsrd = *:4 ea; }
:ldd ea,fdrd is op=3 & fdrd & op3=0x23 & ea { fdrd = *:8 ea; }
:ldq ea,fqrd is op=3 & fqrd & op3=0x22 & ea { fqrd = *:16 ea; }
:ld ea,"%fsr" is op=3 & op3=0x21 & rd=0 & ea { fsr = *:2 ea; }
:ldx ea,"%fsr" is op=3 & op3=0x21 & rd=1 & ea { fsr = *:2 ea; }
:lda ea_alt,fsrd is op=3 & fsrd & op3=0x30 & ea_alt { fsrd = *:4 ea_alt; }
:ldda ea_alt,fdrd is op=3 & fdrd & op3=0x33 & ea_alt { fdrd = *:8 ea_alt; }
:ldqa ea_alt,fqrd is op=3 & fqrd & op3=0x32 & ea_alt { fqrd = *:16 ea_alt; }
:st fsrd,ea is op=3 & fsrd & op3=0x24 & ea { *ea = fsrd:4; }
:std fdrd,ea is op=3 & fdrd & op3=0x27 & ea { *ea = fdrd:8; }
:stq fqrd,ea is op=3 & fqrd & op3=0x26 & ea { *ea = fqrd:16; }
:st "%fsr",ea is op=3 & op3=0x25 & rd=0 & ea { *ea = fsr; }
:stx "%fsr",ea is op=3 & op3=0x25 & rd=1 & ea { *ea = fsr; }
:sta fsrd,ea_alt is op=3 & fsrd & op3=0x34 & ea_alt { *ea_alt = fsrd:4; }
:stda fdrd,ea_alt is op=3 & fdrd & op3=0x37 & ea_alt { *ea_alt = fdrd:8; }
:stqa fqrd,ea_alt is op=3 & fqrd & op3=0x36 & ea_alt { *ea_alt = fqrd:16; }
fcc0_or_fccn: is op2=6 { export fcc0; }
fcc0_or_fccn: is op2=5 & fccn { export fccn; }
fcc: "u" is cond=0x7 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0); export tmp; }
fcc: "u" is cond=0x7 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 3); export tmp; }
fcc: "g" is cond=0x6 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 2); export tmp; }
fcc: "ug" is cond=0x5 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 2 || fcc0_or_fccn == 3); export tmp; }
fcc: "l" is cond=0x4 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1); export tmp; }
@ -1201,33 +1157,36 @@ fcc: "o" is cond=0xf & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn
:fb^fcc^predict "%"fccn,reloff64 is op=0x0 & op2=0x5 & a=0x0 & fcc & reloff64 & predict & fccn { delayslot(1); if (fcc) goto reloff64; }
:fb^fcc^",a"^predict "%"^fccn,reloff64 is op=0x0 & op2=0x5 & a=0x1 & fcc & reloff64 & predict & fccn { if (!fcc) goto inst_next; delayslot(1); goto reloff64; }
define pcodeop fcmps;
define pcodeop fcmpd;
define pcodeop fcmpq;
define pcodeop fcmpes;
define pcodeop fcmped;
define pcodeop fcmpeq;
macro fcmp(f1, f2, fccn) {
# fcc value | relation
# 0 | f1 = f2
# 1 | f1 < f2
# 2 | f1 > f2
# 3 | f1 or f2 NaN
fccn = (1*(f1 f< f2)) + (2*(f1 f> f2)) + (3*(nan(f1) || nan(f2)));
}
:fcmps %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x51 & fsrs1 & fsrs2 { fcmps(fsrs1, fsrs2); }
:fcmpd %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x52 & fdrs1 & fdrs2 { fcmpd(fdrs1, fdrs2); }
:fcmpq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x53 & fqrs1 & fqrs2 { fcmpq(fqrs1, fqrs2); }
:fcmpes %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x55 & fsrs1 & fsrs2 { fcmpes(fsrs1, fsrs2); }
:fcmped %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x56 & fdrs1 & fdrs2 { fcmped(fdrs1, fdrs2); }
:fcmpeq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x57 & fqrs1 & fqrs2 { fcmpeq(fqrs1, fqrs2); }
:fcmps %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x51 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); }
:fcmpd %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x52 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); }
:fcmpq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x53 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); }
:fcmpes %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x55 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); }
:fcmped %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x56 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); }
:fcmpeq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x57 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); }
Z: is opf_cc=4 { export i_zf; }
Z: is opf_cc=6 { export x_zf; }
C: is opf_cc=4 { export i_cf; }
C: is opf_cc=6 { export x_cf; }
N: is opf_cc=4 { export i_nf; }
N: is opf_cc=6 { export x_nf; }
V: is opf_cc=4 { export i_vf; }
V: is opf_cc=6 { export x_vf; }
# floating-point move with integer condition codes
fmicc: "a" is cond4=0x8 { tmp:1=1; export tmp; }
fmicc: "n" is cond4=0x0 { tmp:1=0; export tmp; }
fmicc: "ne" is cond4=0x9 & Z { tmp:1=!Z; export tmp; }
@ -1246,7 +1205,6 @@ fmicc: "vc" is cond4=0xf & 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
fmfcc: "a" is cond4=0x8 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; }
fmfcc: "n" is cond4=0x0 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; }
fmfcc: "u" is cond4=0x7 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; }
@ -1271,12 +1229,15 @@ fcc_icc_xcc: "%"^fccn_4 is bit18=0 & fccn_4 {}
fcc_icc_xcc: "%icc" is bit18=1 & opf_cc=4 { }
fcc_icc_xcc: "%xcc" is bit18=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 { fsrd = fmovs(fcc_icc_xcc, fsrs2); }
:fmovd^fmfcc_or_fmicc fcc_icc_xcc,fdrs2,fdrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=2 & fdrs2 & fdrd { fdrd = fmovd(fcc_icc_xcc, fdrs2); }
: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 { fqrd = fmovq(fcc_icc_xcc, fqrs2); }
: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>}
:fmovd^fmfcc_or_fmicc fcc_icc_xcc,fdrs2,fdrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=2 & fdrs2 & fdrd
{ if !(fmfcc_or_fmicc) goto <end>; fdrd = fdrs2; <end> }
: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> }
:movf^fmfcc_or_fmicc fcc_icc_xcc,regorimm11,rd is op=2 & rd & op3=0x2c & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & regorimm11
{ if (fmfcc_or_fmicc) goto inst_next; rd = regorimm11; }
{ if !(fmfcc_or_fmicc) goto <end>; rd = regorimm11; <end> }
fmovrcc: "z" is rcond3=0x1 & RS1 { tmp:1 = (RS1 f== 0); export tmp; }
fmovrcc: "lez" is rcond3=0x2 & RS1 { tmp:1 = (RS1 f<= 0); export tmp; }
@ -1285,14 +1246,12 @@ fmovrcc: "nz" is rcond3=0x5 & RS1 {tmp:1 = (RS1 f!= 0); export tmp;}
fmovrcc: "gz" is rcond3=0x6 & RS1 { tmp:1 = (RS1 f> 0); export tmp; }
fmovrcc: "gez" is rcond3=0x7 & RS1 { tmp:1 = (RS1 f>= 0); export tmp; }
define pcodeop fmovrs;
define pcodeop fmovrd;
define pcodeop fmovrq;
:fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x5 & fsrs2 { fsrd = fmovrs(RS1, fsrs2); }
:fmovrd^fmovrcc RS1,fdrs2,fdrd is op=2 & fdrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x6 & fdrs2 { fdrd = fmovrd(RS1, fdrs2); }
:fmovrq^fmovrcc RS1,fqrs2,fqrd is op=2 & fqrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x7 & fqrs2 { fqrd = fmovrq(RS1, fqrs2); }
:fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x5 & fsrs2
{ 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
{ 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
{ if !(fmovrcc) goto <end>; fqrd = fqrs2; <end> }
# Include support for the VIS1 vector instructions
@include "SparcVIS.sinc"

View file

@ -1,6 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="2" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="4" />
<wchar_size value="4" />
<short_size value="2" />
<integer_size value="4" />
<long_size value="4" />
<long_long_size value="8" />
<float_size value="4" />
<double_size value="8" />
<long_double_size value="16" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="4" />
<entry size="16" alignment="4" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
</global>
@ -31,6 +53,15 @@
</pentry>
</input>
<output>
<pentry minsize="16" maxsize="16" metatype="float">
<register name="fq0"/>
</pentry>
<pentry minsize="8" maxsize="8" metatype="float">
<register name="fd0"/>
</pentry>
<pentry minsize="4" maxsize="4" metatype="float">
<register name="fs0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="o0"/>
</pentry>

View file

@ -1,6 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="2" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="8" />
<wchar_size value="4" />
<short_size value="2" />
<integer_size value="4" />
<long_size value="4" />
<long_long_size value="8" />
<float_size value="4" />
<double_size value="8" />
<long_double_size value="12" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="4" />
<entry size="16" alignment="4" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
</global>
@ -8,6 +30,30 @@
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<pentry minsize="16" maxsize="16" metatype="float">
<register name="fq0"/>
</pentry>
<pentry minsize="16" maxsize="16" metatype="float">
<register name="fq4"/>
</pentry>
<pentry minsize="16" maxsize="16" metatype="float">
<register name="fq8"/>
</pentry>
<pentry minsize="16" maxsize="16" metatype="float">
<register name="fq12"/>
</pentry>
<pentry minsize="4" maxsize="8" metatype="float">
<register name="fd0"/>
</pentry>
<pentry minsize="4" maxsize="8" metatype="float">
<register name="fd2"/>
</pentry>
<pentry minsize="4" maxsize="8" metatype="float">
<register name="fd4"/>
</pentry>
<pentry minsize="4" maxsize="8" metatype="float">
<register name="fd6"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="o0"/>
</pentry>
@ -31,6 +77,15 @@
</pentry>
</input>
<output>
<pentry minsize="16" maxsize="16" metatype="float">
<register name="fq0"/>
</pentry>
<pentry minsize="8" maxsize="8" metatype="float">
<register name="fd0"/>
</pentry>
<pentry minsize="4" maxsize="4" metatype="float">
<register name="fs0"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="o0"/>
</pentry>

View file

@ -0,0 +1,46 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.program.model.listing.Program;
import ghidra.test.processors.support.EmulatorTestRunner;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class SparcV9_32_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "sparc:BE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public SparcV9_32_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "sparcV9_32_GCC_O0";
}
protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception {
testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_32_O0_EmulatorTest.class);
}
}

View file

@ -0,0 +1,46 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.program.model.listing.Program;
import ghidra.test.processors.support.EmulatorTestRunner;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class SparcV9_32_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "sparc:BE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public SparcV9_32_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "sparcV9_32_GCC_O3";
}
protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception {
testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_32_O3_EmulatorTest.class);
}
}

View file

@ -0,0 +1,46 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.program.model.listing.Program;
import ghidra.test.processors.support.EmulatorTestRunner;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class SparcV9_64_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "sparc:BE:64:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public SparcV9_64_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "sparcV9_64_GCC_O0";
}
protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception {
testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_64_O0_EmulatorTest.class);
}
}

View file

@ -0,0 +1,46 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.program.model.listing.Program;
import ghidra.test.processors.support.EmulatorTestRunner;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class SparcV9_64_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "sparc:BE:64:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public SparcV9_64_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "sparcV9_64_GCC_O3";
}
protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception {
testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_64_O3_EmulatorTest.class);
}
}