--- gforth/arch/alpha/asm.fs 1999/02/02 22:02:54 1.1 +++ gforth/arch/alpha/asm.fs 1999/10/13 13:00:07 1.3 @@ -1,9 +1,12 @@ + \ bernd thallner 9725890 881 \ assembler in forth for alpha \ requires code.fs -also assembler definitions +\ also assembler definitions + +\ register $0 constant v0 $1 constant t0 @@ -38,18 +41,37 @@ $1d constant gp $1e constant sp $1f constant zero -: shift ( a n -- a<<=n ) -0 -?do - 2* -loop +\ util + +: h@ ( addr -- n ) \ 32 bit fetch +dup dup aligned = if + @ + $00000000ffffffff and +else + 4 - @ + $20 rshift +endif ; -: h, ( h -- ) \ 32 bit store +: h! ( n addr -- ) \ 32 bit store +dup dup aligned = if + dup @ + $ffffffff00000000 and + rot or + swap ! +else + 4 - dup @ + $00000000ffffffff and + rot $20 lshift or + swap ! +endif +; + +: h, ( h -- ) \ 32 bit store + allot here here aligned = if here ! else - 32 shift + 32 lshift here 4 - dup @ rot or swap ! @@ -57,43 +79,45 @@ endif 4 allot ; +\ format + : Bra ( oo ) \ branch instruction format create , does> ( ra, branch_disp, addr ) - @ 26 shift + @ 26 lshift swap $1fffff and or - swap $1f and 21 shift or h, + swap $1f and 21 lshift or h, ; : Mbr ( oo.h ) \ memory branch instruction format create 2, does> ( ra, rb, hint, addr ) - 2@ 14 shift - swap 26 shift or + 2@ 14 lshift + swap 26 lshift or swap $3fff and or - swap $1f and 16 shift or - swap $1f and 21 shift or + swap $1f and 16 lshift or + swap $1f and 21 lshift or h, ; : F-P ( oo.fff ) \ floating-point operate instruction format create 2, does> ( fa, fb, fc, addr ) - 2@ 5 shift - swap 26 shift or + 2@ 5 lshift + swap 26 lshift or swap $1f and or - swap $1f and 16 shift or - swap $1f and 21 shift or + swap $1f and 16 lshift or + swap $1f and 21 lshift or h, ; : Mem ( oo ) \ memory instruction format create , does> ( ra, memory_disp, rb, addr ) - @ 26 shift - swap $1f and 16 shift or + @ 26 lshift + swap $1f and 16 lshift or swap $ffff and or - swap $1f and 21 shift or + swap $1f and 21 lshift or h, ; @@ -101,9 +125,9 @@ does> ( ra, memory_disp, rb, addr ) create 2, does> ( ra, rb, addr ) 2@ - swap 26 shift or - swap $1f and 16 shift or - swap $1f and 21 shift or + swap 26 lshift or + swap $1f and 16 lshift or + swap $1f and 21 lshift or h, ; @@ -111,11 +135,11 @@ does> ( ra, rb, addr ) create 2, does> ( ra, rb, rc, addr ) 2@ - 5 shift - swap 26 shift or + 5 lshift + swap 26 lshift or swap $1f and or - swap $1f and 16 shift or - swap $1f and 21 shift or + swap $1f and 16 lshift or + swap $1f and 21 lshift or h, ; @@ -123,23 +147,25 @@ does> ( ra, rb, rc, addr ) create 2, does> ( ra, lit, rc, addr ) 2@ - 5 shift - swap 26 shift or - 1 12 shift or + 5 lshift + swap 26 lshift or + 1 12 lshift or swap $1f and or - swap $ff and 13 shift or - swap $1f and 21 shift or + swap $ff and 13 lshift or + swap $1f and 21 lshift or h, ; : Pcd ( oo ) \ palcode instruction format create , does> ( palcode, addr ) - @ 26 shift + @ 26 lshift swap $3ffffff and or h, ; +\ instructions + $15 $80 F-P addf, $15 $a0 F-P addg, $10 $00 Opr addl, @@ -374,3 +400,160 @@ $12 $30 Opr# zap#, $12 $31 Opr zapnot, $12 $31 Opr# zapnot#, +\ structures + +\ if, [ else, ] endif, + +: ahead, ( -- asmorig ) + 31 0 br, + here 4 - +; + +: if, ( -- asmorig ) + 0 beq, + here 4 - +; + +: endif, ( asmorig -- ) + dup here swap - 4 - 4 / + $1fffff and + over h@ or swap h! +; + +: else, ( asmorig1 -- asmorig2 ) + ahead, + swap + endif, +; + +\ begin, again, + +: begin, ( -- asmdest ) + here +; + +: again, ( asmdest -- ) + here - 4 - 4 / + $1fffff and + 31 swap br, +; + +\ begin, until, + +: until, ( asmdest -- ) + here rot swap - 4 - 4 / + $1fffff and + bne, +; + +\ begin, while, repeat, + +: while, ( asmdest -- asmorig asmdest ) + if, + swap +; + +: repeat, ( asmorig asmdest -- ) + again, + endif, +; + +\ jump marks + +\ example: + +\ init_marktbl \ initializes mark table +\ 31 0 br, +\ 0 store_branch \ store jump address for mark 0 +\ 1 2 3 addf, +\ 0 set_mark \ store mark 0 +\ 2 3 4 addf, +\ 2 0 beq, +\ 0 store_branch \ store jump address for mark 0 +\ calculate_marks \ calculate all jumps + +\ with calculate_branch you can calculate the +\ displacement field without the mark_table for one branch + +\ example: +\ here 31 0 br, +\ here 1 2 3 addf, +\ calculate_branch + +5 constant mark_numbers +5 constant mark_uses + +create mark_table +mark_numbers mark_uses 1+ * cells allot + +: init_marktbl ( -- ) \ initializes mark table + mark_table mark_numbers mark_uses 1+ * cells + + mark_table + begin + over over > + while + dup 0 swap ! + 1 cells + + repeat + drop drop +; + +: set_mark ( mark_number -- ) \ sets mark, store address in mark table + dup mark_numbers >= abort" error, illegal mark number" + mark_uses 1+ * cells + mark_table + here 8 - swap ! +; + +: store_branch ( mark_number -- ) \ stores address of branch in mark table + dup mark_numbers >= abort" error, illegal mark number" + mark_uses 1+ * cells + mark_table + 1 cells + + dup mark_uses cells + swap + begin + over over > over @ and + while + 1 cells + + repeat + swap over = abort" error, not enough space in mark_table, increase mark_uses" + here 4 - swap ! +; + +: calculate_branch ( mark_addr branch_addr -- ) \ calculate branch displacement field for one branch + swap over - 4 + 4 / + $1fffff and + over h@ or swap h! +; + +: calculate_mark ( tb mark_address -- tb ) \ calculates branch displacement field for one mark + over 1 cells + + dup mark_uses cells + swap + begin + over over > + while + 2over swap drop ( ei i markaddr ej j markaddr ) + over @ + dup if + calculate_branch + else + drop drop + endif + 1 cells + + repeat drop drop drop +; + +: calculate_marks ( -- ) \ calculates branch displacement field for all marks + mark_table mark_numbers 1- mark_uses 1+ * cells + + mark_table + begin + over over >= + while + dup @ + dup if \ used mark + calculate_mark + else + drop + endif + mark_uses 1+ cells + + repeat + drop drop +;