! 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],%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+136],%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+136] ! %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+132] ! 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] ! All saved, restore back to the pc-save window and return. restore ret restore