! See reald.txt for notes. .data .align 4 exec_loc: .long 0 ! instruction under test save %sp,-104,%sp sethi_loc: .long 0 ! sethi %hi(...),%l0 or_loc: .long 0 ! or %l0,...,%l0 call_loc: .long 0 ! call after nop .text .global doit .align 4 doit: save %sp,-104,%sp ! Now in the return-pc-save window. mov %i0,%o0 save %sp,-104,%sp ! Now in the execution window. mov %i0,%o0 ! Our input data pointer is in %o0. Set up most registers. ! Offsets are 4 higher than you might expect because the +0 ! location holds the instruction. ! don't bother with %g0 ld [%o0+8],%g1 ld [%o0+12],%g2 ld [%o0+16],%g3 ld [%o0+20],%g4 ld [%o0+24],%g5 ld [%o0+28],%g6 ld [%o0+32],%g7 ld [%o0+68],%l0 ld [%o0+72],%l1 ld [%o0+76],%l2 ld [%o0+80],%l3 ld [%o0+84],%l4 ld [%o0+88],%l5 ld [%o0+92],%l6 ld [%o0+96],%l7 ld [%o0+100],%i0 ld [%o0+104],%i1 ld [%o0+108],%i2 ld [%o0+112],%i3 ld [%o0+116],%i4 ld [%o0+120],%i5 ! don't bother with %i6 = %fp ld [%o0+128],%i7 ld [%o0+132],%f0 ld [%o0+136],%f1 ld [%o0+140],%f2 ld [%o0+144],%f3 ld [%o0+148],%f4 ld [%o0+152],%f5 ld [%o0+156],%f6 ld [%o0+160],%f7 ld [%o0+164],%f8 ld [%o0+168],%f9 ld [%o0+172],%f10 ld [%o0+176],%f11 ld [%o0+180],%f12 ld [%o0+184],%f13 ld [%o0+188],%f14 ld [%o0+192],%f15 ld [%o0+196],%f16 ld [%o0+200],%f17 ld [%o0+204],%f18 ld [%o0+208],%f19 ld [%o0+212],%f20 ld [%o0+216],%f21 ld [%o0+220],%f22 ld [%o0+224],%f23 ld [%o0+228],%f24 ld [%o0+232],%f25 ld [%o0+236],%f26 ld [%o0+240],%f27 ld [%o0+244],%f28 ld [%o0+248],%f29 ld [%o0+252],%f30 ld [%o0+256],%f31 ld [%o0+260],%o1 wr %o1,%y ! Execution window now ready, except for %o0-%o7 and cc. ! Shift to scratch window. save %sp,-104,%sp mov %i0,%o0 ! Input data pointer now in %o0. set exec_loc,%o1 ld [%o0],%l7 st %l7,[%o1] flush %o1 set sethi_loc,%l0 set 0x21000000,%l2 ! fixed bits of sethi ...,%l0 srl %o0,10,%l1 or %l1,%l2,%l1 st %l1,[%l0] flush %l0 set or_loc,%l0 set 0x000003ff,%l1 ! low 10 bits set 0xa0142000,%l3 ! fixed bits of or %l0,...,%l0 and %o0,%l1,%l2 or %l2,%l3,%l2 st %l2,[%l0] flush %l0 set after,%l1 set call_loc,%l2 sub %l1,%l2,%l3 sethi %hi(0x40000000),%l4 ! fixed bits of call srl %l3,2,%l3 or %l3,%l4,%l3 st %l3,[%l2] flush %l2 ! That was the last flush. It can now take up to five ! instructions before we can count on everything being ! consistent. Fortunately, we have way more than five ! instructions before we want to do anything depending on the ! code we just constructed. stbar ! Code now set up. ! Input data pointer now in %o0, exec_loc in %o1. ! Set up the condition codes. ld [%o0+264],%o3 set setcc_code,%o2 and %o3,15,%o3 sll %o3,2,%o3 add %o3,%o2,%o3 ld [%o3],%o3 jmpl %o3,%g0 nop setcc_code: .long setcc_____ .long setcc____c .long setcc___v_ .long setcc___vc .long setcc__z__ .long setcc__z_c .long setcc__zv_ .long setcc__zvc .long setcc_n___ .long setcc_n__c .long setcc_n_v_ .long setcc_n_vc .long setcc_nz__ .long setcc_nz_c .long setcc_nzv_ .long setcc_nzvc setcc_____: ba setcc_done inccc %g0 setcc____c: set 0x80010000,%o4 ba setcc_done subcc %g0,%o4,%g0 setcc___v_: set 0x80000000,%o3 ba setcc_done subcc %o3,1,%g0 setcc___vc: set 0x80010000,%o3 ba setcc_done addcc %o3,%o3,%g0 setcc__z__: ba setcc_done tst %g0 setcc__z_c: set 0x80000400,%o3 sub %o3,0x800,%o4 ba setcc_done addcc %o3,%o4,%g0 setcc__zv_: set 1,%o3 ba setcc_done tsubcc %o3,%o3,%g0 setcc__zvc: set 0x80000000,%o3 ba setcc_done addcc %o3,%o3,%g0 setcc_n___: ba setcc_done xnorcc %g0,%g0,%g0 setcc_n__c: ba setcc_done deccc %g0 setcc_n_v_: set 0x40000000,%o3 ba setcc_done addcc %o3,%o3,%g0 setcc_n_vc: set 0x00010000,%o3 set 0x80000000,%o4 ba setcc_done subcc %o3,%o4,%g0 ! I think these next four can't be done without privilege.... setcc_nz__: setcc_nz_c: setcc_nzv_: setcc_nzvc: ba setcc_done tst %g0 setcc_done: ! Can't do anything from here on that affects cc ld [%o0+36],%i0 ld [%o0+40],%i1 ld [%o0+44],%i2 ld [%o0+48],%i3 ld [%o0+52],%i4 ld [%o0+56],%i5 ! don't bother with %i6 = %fp (%sp of execution window) ld [%o0+64],%i7 ! Go do it! jmpl %o1,%g0 restore after: ! We come here via call after executing. ! %l0 holds our input data pointer. ! We are already in our scratch window. mov %g0,%l1 bneg,a 1f or %l1,8,%l1 1: be,a 1f or %l1,4,%l1 1: bvs,a 1f or %l1,2,%l1 1: bcs,a 1f or %l1,1,%l1 1: st %l1,[%l0+264] ! %i0-%i7 here are %o0-%o7 of execution window st %i0,[%l0+36] st %i1,[%l0+40] st %i2,[%l0+44] st %i3,[%l0+48] st %i4,[%l0+52] st %i5,[%l0+56] st %i7,[%l0+64] rd %y,%i0 st %i0,[%l0+260] ! Back to execution window, but first save %l0 mov %l0,%i0 restore ! Now capture the rest of the registers st %g0,[%o0+4] st %g1,[%o0+8] st %g2,[%o0+12] st %g3,[%o0+16] st %g4,[%o0+20] st %g5,[%o0+24] st %g6,[%o0+28] st %g7,[%o0+32] st %l0,[%o0+68] st %l1,[%o0+72] st %l2,[%o0+76] st %l3,[%o0+80] st %l4,[%o0+84] st %l5,[%o0+88] st %l6,[%o0+92] st %l7,[%o0+96] st %i0,[%o0+100] st %i1,[%o0+104] st %i2,[%o0+108] st %i3,[%o0+112] st %i4,[%o0+116] st %i5,[%o0+120] ! don't bother with %i6 = %fp st %i7,[%o0+128] st %f0,[%o0+132] st %f1,[%o0+136] st %f2,[%o0+140] st %f3,[%o0+144] st %f4,[%o0+148] st %f5,[%o0+152] st %f6,[%o0+156] st %f7,[%o0+160] st %f8,[%o0+164] st %f9,[%o0+168] st %f10,[%o0+172] st %f11,[%o0+176] st %f12,[%o0+180] st %f13,[%o0+184] st %f14,[%o0+188] st %f15,[%o0+192] st %f16,[%o0+196] st %f17,[%o0+200] st %f18,[%o0+204] st %f19,[%o0+208] st %f20,[%o0+212] st %f21,[%o0+216] st %f22,[%o0+220] st %f23,[%o0+224] st %f24,[%o0+228] st %f25,[%o0+232] st %f26,[%o0+236] st %f27,[%o0+240] st %f28,[%o0+244] st %f29,[%o0+248] st %f30,[%o0+252] st %f31,[%o0+256] ! All saved, restore back to the pc-save window and return. restore ret restore