--- /dev/null
+EM_table
+EM_table.x
+Makefile
+back.src
+cache.c
+cache.c.x
+ce.src
+cegpp
+mach.c
+mach.h
+mach_em.h
+misc.h
+ms_reg.h
+proto.make
+push_pop.h
--- /dev/null
+/* lfr ret should little endian */
+
+#define const13(x) ((x) > -4096 && (x) < 4096)
+#define NULL 0
+#include "mach_em.h"
+
+define(`RETH_LD',`reg_o1')
+define(`RETL_LD',`reg_o0')
+define(`RETH_ST',`reg_i1')
+define(`RETL_ST',`reg_i0')
+define(`LIN_NO',`%g6')
+define(`FIL_NAM',`%g7')
+define(O0, reg_o0)
+define(O1, reg_o1)
+define(O2, reg_o2)
+define(O3, reg_o3)
+
+define(`BP_OFFSET',`'WINDOWSIZE)
+define(`'`EM_BSIZE',EM_BSIZE)
+define(STACK_CLICK,4)
+
+#if RESOLVE_debug
+define(Comment0)
+define(Comment)
+define(Comment2)
+#else
+define(Comment0,; `'`)' ; `'`/* */'" ! $1" ; code_combiner`'`(' )
+define(Comment, ; `'`)' ; `'`/* */'" ! $1 $2" ; code_combiner`'`(' )
+define(Comment2,; `'`)' ; `'`/* */'" ! $1 $2 $3" ; code_combiner`'`(' )
+#endif
+
+define(MAX_INT, 0x7fffffff)
+define(E_EM_CUF, 100)
+define(E_EM_CFF, 101)
+define(E_EM_CFI, 102)
+define(E_EM_CFU, 103)
+#define MAX_UNROLL 16
+#undef FAST_LIN_LNI_FIL
+
+
+define( narg4,
+C_$1_narg ==>
+` {
+ reg_t a;
+ int n;
+
+ Comment0( $1_narg );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ C_$1 (n);
+ }
+ else
+ {
+ a= pop_reg();
+ force_alloc_output();
+ "cmp $a, 4";
+ "be 1f";
+ "set EILLINS, $reg_o0";
+ "call trp";
+ "nop";
+ "1:";
+ free_reg(a);
+ free_output();
+ C_$1 (4);
+ }
+ }.
+'
+)
+
+
+/******************************************************************************/
+/* */
+/* Group 1 : Load instructions */
+/* */
+/******************************************************************************/
+
+/* %fp : frame pointer
+ * %sp : stack pointer
+ * RETH_XX: High part of return value
+ * RETL_XX: Low part of return value
+ * LIN_NO : lin_no
+ * FIL_NAM: Fil_nam
+ */
+
+C_loc ==>
+ Comment( loc , $1 );
+ push_const($1).
+
+
+C_lol ==>
+ Comment( lol , $1 );
+ {
+ reg_t S1;
+
+ if (S1 = find_local($1, NULL)) {
+ soft_alloc_reg(S1);
+ push_reg(S1);
+ } else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ push_const(4);
+ C_los(EM_WSIZE);
+ }
+ }.
+
+
+C_loe.. ==>
+ Comment2( loe.. , $1, $2 );
+ {
+#ifdef FAST_LIN_LNI_FIL
+ if ((int*)($1) == (int*)"hol0")
+ if ($2 == 0)
+ push_reg(reg_lin);
+ else if ($2 == 4)
+ push_reg(reg_fil);
+ else
+ arg_error("loe.. hol0+", $2);
+ else {
+#endif
+ push_ext($1);
+ inc_tos($2);
+ push_const(4);
+ C_los(EM_WSIZE);
+#ifdef FAST_LIN_LNI_FIL
+ }
+#endif
+ }
+ .
+
+C_lil ==>
+ Comment( lil , $1 );
+ {
+ reg_t S1;
+ reg_t S2;
+
+ if (S1 = find_local($1, NULL)) {
+ S2 = alloc_reg();
+ "ld [$S1], $S2";
+ push_reg(S2);
+ } else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ push_const(4);
+ C_los(EM_WSIZE);
+ push_const(4);
+ C_los(EM_WSIZE);
+ }
+ }.
+
+C_lof ==>
+ Comment( lof , $1 );
+ inc_tos($1);
+ push_const(4);
+ C_los(EM_WSIZE).
+
+C_lal ==>
+ Comment( lal , $1 );
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1).
+
+C_lae.. ==>
+ Comment2( lae.. , $1, $2 );
+ push_ext($1);
+ inc_tos($2).
+
+C_lxl
+ $1 == 0 ==>
+ Comment( lxl , $1 );
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb).
+ $1 == 1 ==>
+ Comment( lxl , $1 );
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos(EM_BSIZE);
+ push_const(4);
+ C_los(EM_WSIZE).
+ default ==>
+ Comment( lxl , $1 );
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ const_str_t n_str;
+
+ a = alloc_reg();
+ b = alloc_reg();
+ c = alloc_reg();
+ sprintf(n_str, "%d", $1);
+ "set $n_str, $a";
+ "mov $reg_lb, $b";
+ "1: ld [$b + EM_BSIZE], $c";
+ "deccc $a";
+ "bnz 1b";
+ "mov $c, $b";
+ push_reg(b);
+ free_reg(a);
+ free_reg(c);
+ }.
+
+C_lxa ==>
+ C_lxl($1);
+ inc_tos(EM_BSIZE).
+
+C_loi
+ ( $1 == 1 ) ||
+ ( $1 == 2 ) ||
+ ( $1 % 4 == 0 ) ==>
+ Comment( loi , $1 );
+ push_const($1);
+ C_los(EM_WSIZE).
+
+ default ==>
+ arg_error( "loi", $1).
+
+C_los
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ int i;
+ char *LD;
+ arith size;
+ const_str_t n;
+ const_str_t size_str;
+
+ Comment( los, $1);
+ if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL) {
+ size = pop_const(size_str);
+ if (size <= 4) {
+ switch (size) {
+ case 1: LD = "ldub"; break;
+ case 2: LD = "lduh"; break;
+ case 4: LD = "ld"; break;
+ default: arg_error("C_los", size);
+ }
+ b = alloc_reg();
+ if (type_of_tos() & T_reg2)
+ {
+ a= pop_reg_reg(&c);
+ "$LD [$a+$c], $b";
+ free_reg(a);
+ free_reg(c);
+ }
+ else
+ {
+ a = pop_reg_c13(n);
+ "$LD [$a+$n], $b";
+ free_reg(a);
+ }
+ push_reg(b);
+ } else if (size <= MAX_UNROLL) { /* SUB-OPTIMAL */
+ inc_tos(size-4);
+ for (i = 0; i < size; i += 4) {
+ b = alloc_reg();
+ if (type_of_tos() & T_reg2)
+ {
+ a= pop_reg_reg(&c);
+ "ld [$a+$c], $b";
+ push_reg(b);
+ push_reg(a);
+ inc_tos_reg(c);
+ }
+ else
+ {
+ a = pop_reg_c13(n);
+ "ld [$a+$n], $b";
+ push_reg(b);
+ if (n[0] == '-' || isdigit(n[0]))
+ {
+ push_reg(a);
+ inc_tos(atoi(n));
+ }
+ else
+ {
+ b= alloc_reg();
+ "add $a, $n, $b";
+ push_reg(b);
+ free_reg(a);
+ }
+ }
+ inc_tos(-4);
+ }
+ pop_nop(1);
+ } else
+ arg_error ("loi", size);
+ }
+ else {
+ a = pop_reg(); /* count */
+ b = pop_reg(); /* addr */
+ c = alloc_reg();
+ flush_cache();
+ "sub $reg_sp, $a, $reg_sp" /* HACK */
+ "1: deccc 4, $a"
+ "ld [$b+$a], $c"
+ "bnz 1b"
+ "st $c, [$reg_sp+$a]" /* delay */
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ }
+ }.
+ default ==>
+ arg_error("C_los", $1).
+
+
+narg4(los)
+
+C_ldl ==>
+ Comment( ldl , $1 );
+ {
+ reg_t S1;
+ reg_t S2;
+
+ if (S1 = find_local($1, &S2)) {
+ soft_alloc_reg(S1);
+ soft_alloc_reg(S2);
+ push_double_reg(S1);
+ } else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ push_const(8);
+ C_los(EM_WSIZE);
+ }
+ }.
+
+
+C_lde.. ==>
+ Comment2( lde.. , $1, $2 );
+ push_ext($1);
+ inc_tos($2);
+ push_const(8);
+ C_los(EM_WSIZE).
+
+C_ldf ==>
+ Comment( ldf , $1 );
+ inc_tos($1);
+ push_const(8);
+ C_los(EM_WSIZE).
+
+C_lpi ==>
+ Comment( lpi , $1 );
+ push_ext($1).
+
+
+/******************************************************************************/
+/* */
+/* Group 2 : Store instructions */
+/* */
+/******************************************************************************/
+
+C_stl ==>
+ Comment( stl , $1 );
+ {
+ reg_t S1;
+
+ if ((S1 = find_local($1, NULL))) {
+ pop_reg_as(S1);
+ } else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ push_const(4);
+ C_sts(EM_WSIZE);
+ }
+ }.
+
+C_ste.. ==>
+ Comment2( ste.. , $1, $2 );
+ push_ext($1);
+ inc_tos($2);
+ push_const(4);
+ C_sts(EM_WSIZE).
+
+
+C_sil ==>
+ Comment( sil , $1 );
+ {
+ reg_t S1;
+ reg_t S2;
+
+ if (S1 = find_local($1, NULL)) {
+ S2 = pop_reg();
+ "st $S2, [$S1]";
+ free_reg(S2);
+ } else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ push_const(4);
+ C_los(EM_WSIZE);
+ push_const(4);
+ C_sts(EM_WSIZE);
+ }
+ }.
+
+C_stf ==>
+ Comment( stf , $1 );
+ inc_tos($1);
+ push_const(4);
+ C_sts(EM_WSIZE).
+
+C_sti
+ ( $1 == 1) ||
+ ( $1 == 2) ||
+ ( $1 % 4 == 0 ) ==>
+ Comment( sti, $1 );
+ push_const($1);
+ C_sts(EM_WSIZE).
+
+ default ==>
+ arg_error( "loi", $1).
+
+
+C_sts
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+
+ arith size;
+ const_str_t n;
+ const_str_t size_str;
+ int i;
+ char *ST;
+
+ Comment( sts, $1);
+ if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL) {
+
+ size = pop_const(size_str);
+ if (size <= 4) {
+
+ switch (size) {
+ case 1: ST = "stb"; break;
+ case 2: ST = "sth"; break;
+ case 4: ST = "st"; break;
+ default: arg_error("C_sti", size);
+ }
+ c= NULL;
+ if (type_of_tos() & T_reg2)
+ a= pop_reg_reg(&c);
+ else
+ a = pop_reg_c13(n);
+ if (type_of_tos() == T_float)
+ b= pop_float();
+ else
+ b = pop_reg();
+ if (c)
+ {
+ "$ST $b, [$a+$c]";
+ free_reg(c);
+ }
+ else
+ "$ST $b, [$a+$n]";
+ free_reg(a);
+ free_reg(b);
+ } else if (size <= MAX_UNROLL) {
+ for (i = 0; i < size; i+=4) {
+ c= NULL;
+ if (type_of_tos() & T_reg2)
+ a= pop_reg_reg(&c);
+ else
+ a = pop_reg_c13(n);
+ if (type_of_tos() == T_float)
+ b= pop_float();
+ else
+ b = pop_reg();
+ if (c)
+ "st $b, [$a+$c]";
+ else
+ "st $b, [$a+$n]";
+ free_reg(b);
+ if (c)
+ {
+ push_reg(a);
+ inc_tos_reg(c);
+ }
+ else if (n[0] == '-' || isdigit(n[0]))
+ {
+ push_reg(a);
+ inc_tos(atoi(n));
+ }
+ else
+ {
+ b= alloc_reg();
+ "add $a, $n, $b";
+ push_reg(b);
+ free_reg(a);
+ }
+ inc_tos(4);
+ }
+ pop_nop(1);
+ } else
+ arg_error ("sti", size);
+ }
+ else {
+ force_alloc_output();
+ d = pop_reg(); /* size */
+ a = pop_reg(); /* address */
+ flush_cache();
+ b = alloc_reg();
+ c = alloc_reg();
+ "cmp $d, 4";
+ "bg,a 8f";
+ "andcc $d, 3, %g0"; /* delay slot */
+ "be,a 4f";
+ "ld [$reg_sp], $b"; /* delay slot */
+ "cmp $d, 1";
+ "be,a 1f";
+ "ld [$reg_sp], $b"; /* delay slot */
+ "bl 0f";
+ "cmp $d, 2";
+ "be 2f";
+ "ld [$reg_sp], $b"; /* delay slot */
+ "3: set EILLINS, %o0";
+ "call trp";
+ "nop";
+ "b 0f";
+ "nop";
+ "1:";
+ "inc STACK_CLICK, $reg_sp";
+ "b 0f";
+ "stb $b, [$a]"; /* delay slot */
+ "2:";
+ "inc STACK_CLICK, $reg_sp";
+ "b 0f";
+ "sth $b, [$a]"; /* delay slot */
+ "4:";
+ "inc STACK_CLICK, $reg_sp";
+ "b 0f";
+ "st $b, [$a]"; /* delay slot */
+ "8:";
+ "bne 3b";
+ "nop";
+ "mov $d, $b";
+ "9: deccc 4, $b";
+ "ld [$reg_sp+$b], $c";
+ "bnz 9b";
+ "st $c, [$a+$b]"; /* delay slot */
+ "add $reg_sp, $d, $reg_sp" /* HACK */
+ "0:"
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_output();
+ }
+ }.
+ default ==>
+ arg_error( "sts", $1).
+
+narg4(sts)
+
+C_sdl ==>
+ Comment( sdl , $1 );
+ {
+ reg_t S1;
+ reg_t S2;
+
+ S1 = find_local($1, NULL);
+ if (S1)
+ pop_double_reg_as(S1);
+ else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ push_const(8);
+ C_sts(EM_WSIZE);
+ }
+ }.
+
+C_sde.. ==>
+ Comment2( sde.. , $1, $2 );
+ push_ext($1);
+ inc_tos($2);
+ push_const(8);
+ C_sts(EM_WSIZE).
+
+C_sdf ==>
+ Comment( sdf , $1 );
+ inc_tos($1);
+ push_const(8);
+ C_sts(EM_WSIZE).
+
+
+/******************************************************************************/
+/* */
+/* Group 3 : Integer arithmetic */
+/* */
+/******************************************************************************/
+
+
+C_adi
+ $1 == 4 ==>
+ Comment( adi , $1 );
+ if ((type_of_tos()) == T_cst) {
+ arith n;
+
+ n = pop_const(NULL);
+ inc_tos(n);
+ } else {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ a = pop_reg();
+ inc_tos_reg(a);
+ }.
+ default ==>
+ arg_error( "adi", $1).
+
+narg4(adi)
+
+C_sbi
+ $1 == 4 ==>
+ Comment( sbi , $1 );
+ if ((type_of_tos()) == T_cst) {
+ arith n;
+
+ n = pop_const(NULL);
+ inc_tos(-n);
+ } else {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ a = pop_reg();
+ b = pop_reg();
+ c = alloc_reg();
+ "sub $b, $a, $c";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }.
+ default ==>
+ arg_error( "sbi", $1).
+
+narg4(sbi)
+
+C_mli
+ $1 == 4 ==>
+ {
+ unsigned int n0;
+ unsigned int n1;
+ reg_t orig;
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ unsigned int n;
+ const_str_t n_str;
+
+ Comment( mli , $1 );
+
+ if (type_of_tos() == T_cst) {
+ n = pop_const(NULL);
+ orig = pop_reg();
+ c = reg_g0;
+ while (n) {
+ for (n0 = 0; !(n & 1); n>>=1)
+ ++n0;
+ for (n1 = 0; n & 1; n>>=1)
+ ++n1;
+
+ if (n0) {
+ a = alloc_reg();
+ sprintf(n_str, "%d", n0);
+ "sll $orig, $n_str, $a";
+ free_reg(orig);
+ orig = a;
+ }
+ if (n1 == 1) {
+ if (c == reg_g0) {
+ soft_alloc_reg(orig);
+ c = orig;
+ } else {
+ a = alloc_reg();
+ "add $c, $orig, $a";
+ free_reg(c);
+ c = a;
+ }
+ n <<= n1;
+ } else {
+ a = alloc_reg();
+ sprintf(n_str, "%d", n1);
+ "sll $orig, $n_str, $a";
+ b = alloc_reg();
+ "sub $a, $orig, $b";
+ free_reg(orig);
+ orig = a;
+ if (c == reg_g0)
+ c = b;
+ else {
+ a = alloc_reg();
+ "add $c, $b, $a";
+ free_reg(b);
+ free_reg(c);
+ c = a;
+ }
+ }
+ }
+ push_reg(c);
+ free_reg(orig);
+ } else {
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ pop_reg_as(reg_o1);
+ "call mli4";
+ "nop" /* delay */
+ free_output();
+ forced_alloc_reg(O0);
+ push_reg(O0);
+ }
+ }.
+ default ==>
+ arg_error( "mli", $1).
+
+narg4(mli)
+
+C_dvi
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ int n;
+ int n_exp;
+ const_str_t n_exp_str;
+
+ Comment( dvi , $1 );
+#if MATH_DIVIDE
+ if (type_of_tos() == T_cst &&
+ power_of_2(top_const(), &n_exp))
+ {
+ sprintf (n_exp_str, "%d", n_exp);
+ n= pop_const(NULL);
+ a= pop_reg();
+ if (n <0)
+ {
+ b= alloc_reg();
+ "neg $a, $b";
+ free_reg(a);
+ a= b;
+ }
+ b= alloc_reg();
+ "srl $a, $n_exp_str, $b";
+ free_reg(a);
+ push_reg(b);
+ }
+ else
+ {
+ force_alloc_output();
+ pop_reg_as(reg_o1); /* denominator */
+ pop_reg_as(reg_o0); /* numerator */
+ "call dvi4";
+ "nop"
+ free_output();
+ forced_alloc_reg(reg_o0);
+ push_reg(reg_o0);
+ }
+#else
+ not_implemented("dvi");
+#endif /* MATH_DIVIDE */
+ }.
+ default ==>
+ arg_error( "dvi", $1).
+
+narg4(dvi)
+
+C_rmi
+ $1 == 4 ==>
+ Comment( rmi , $1 );
+ {
+ force_alloc_output();
+ pop_reg_as(reg_o1); /* denominator */
+ pop_reg_as(reg_o0); /* numerator */
+ "call dvi4";
+ "nop"
+ free_output();
+ forced_alloc_reg(O1);
+ push_reg(O1);
+ }.
+ default ==>
+ arg_error( "rmi", $1).
+
+narg4(rmi)
+
+C_ngi
+ $1 == 4 ==>
+ Comment( ngi , $1 );
+ {
+ reg_t a;
+ reg_t b;
+
+ a = pop_reg();
+ b = alloc_reg();
+ "sub %g0, $a, $b";
+ push_reg(b);
+ free_reg(a);
+ }.
+ default ==>
+ arg_error( "ngi", $1).
+
+narg4(ngi)
+
+C_sli
+ $1 == 4 ==>
+ Comment( sli , $1 );
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ b = alloc_reg();
+ if ((type_of_tos() == T_cst) &&
+ (const13(top_const()))) {
+ const_str_t n;
+
+ pop_const(n);
+ a = pop_reg();
+ "sll $a, $n, $b";
+ } else {
+ c = pop_reg();
+ a = pop_reg();
+ "sll $a, $c, $b";
+ free_reg(c);
+ }
+ free_reg(a);
+ push_reg(b);
+ }.
+ default ==>
+ arg_error( "sli", $1).
+
+narg4(sli)
+
+C_sri
+ $1 == 4 ==>
+ Comment( sri , $1 );
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ b = alloc_reg();
+ if ((type_of_tos() == T_cst) &&
+ (const13(top_const()))) {
+ const_str_t n;
+
+ pop_const(n);
+ a = pop_reg();
+ "sra $a, $n, $b";
+ } else {
+ c = pop_reg();
+ a = pop_reg();
+ "sra $a, $c, $b";
+ free_reg(c);
+ }
+ free_reg(a);
+ push_reg(b);
+ }.
+ default ==>
+ arg_error( "sri", $1).
+
+narg4(sri)
+
+/******************************************************************************/
+/* */
+/* Group 4 : Unsigned arithmetic */
+/* */
+/******************************************************************************/
+
+C_adu ==>
+ Comment( adu , $1 );
+ C_adi( w).
+
+narg4(adu)
+
+C_sbu ==>
+ Comment( sbu , $1 );
+ C_sbi( w).
+
+narg4(sbu)
+
+C_mlu
+ $1 == 4 ==>
+ Comment( mlu , $1 );
+ C_mli($1).
+/*
+ {
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ pop_reg_as(reg_o1);
+ "call mlu4";
+ "nop"
+ free_output();
+ forced_alloc_reg(O0);
+ push_reg(O0);
+ }.
+*/
+ default ==>
+ arg_error( "mlu", $1).
+
+narg4(mlu)
+
+C_dvu
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ unsigned n;
+ int n_exp;
+ const_str_t n_exp_str;
+
+ Comment( dvu , $1 );
+ if (type_of_tos() == T_cst &&
+ uns_power_of_2(top_const(), &n_exp))
+ {
+ sprintf (n_exp_str, "%d", n_exp);
+ n= pop_const(NULL);
+ a= pop_reg();
+ b= alloc_reg();
+ "srl $a, $n_exp_str, $b";
+ free_reg(a);
+ push_reg(b);
+ }
+ else
+ {
+ force_alloc_output();
+ pop_reg_as(reg_o1); /* denominator */
+ pop_reg_as(reg_o0); /* numerator */
+ "call dvu4";
+ "nop"
+ free_output();
+ forced_alloc_reg(reg_o0);
+ push_reg(reg_o0);
+ }
+ }.
+ default ==>
+ arg_error( "dvu", $1).
+
+narg4(dvu)
+
+C_rmu
+ $1 == 4 ==>
+ Comment( rmu , $1 );
+ {
+ force_alloc_output();
+ pop_reg_as(reg_o1);
+ pop_reg_as(reg_o0);
+ "call dvu4";
+ "nop"
+ free_output();
+ forced_alloc_reg(O1);
+ push_reg(O1);
+ }.
+ default ==>
+ arg_error( "rmu", $1).
+
+narg4(rmu)
+
+C_slu ==>
+ Comment( slu , $1 );
+ C_sli($1).
+
+narg4(slu)
+
+C_sru
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ Comment( sru , $1 );
+ b = alloc_reg();
+ if ((type_of_tos() == T_cst) &&
+ (const13(top_const()))) {
+ const_str_t n;
+
+ pop_const(n);
+ a = pop_reg();
+ "srl $a, $n, $b";
+ } else {
+ c = pop_reg();
+ a = pop_reg();
+ "srl $a, $c, $b";
+ free_reg(c);
+ }
+ free_reg(a);
+ push_reg(b);
+ }.
+ default ==>
+ arg_error( "sru", $1).
+
+narg4(sru)
+
+/******************************************************************************/
+/* */
+/* Group 5 : Floating point arithmetic */
+/* */
+/******************************************************************************/
+
+C_adf ==>
+ {
+ Comment( adf, $1);
+ push_const($1);
+ C_adf_narg();
+ }.
+
+C_adf_narg ==>
+ {
+ reg_t f1;
+ reg_t f2;
+ reg_t f3;
+ int n;
+
+ Comment0( adf_narg);
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n == EM_WSIZE)
+ {
+ f1= pop_float();
+ inc_tos_reg(f1);
+ }
+ else if (n == EM_DSIZE)
+ {
+ f1= pop_double(NULL);
+ f2= pop_double(NULL);
+ f3= alloc_double(NULL);
+ "faddd $f1, $f2, $f3";
+ free_double_reg(f1);
+ free_double_reg(f2);
+ push_double_reg(f3);
+ }
+ else
+ arg_error ("unimp adf", n);
+ }
+ else
+ not_implemented ("adf_narg");
+ }.
+
+C_sbf ==>
+ {
+ Comment( sbf, $1);
+ push_const($1);
+ C_sbf_narg();
+ }.
+
+C_sbf_narg ==>
+ {
+ reg_t f1;
+ reg_t f2;
+ reg_t f3;
+ int n;
+
+ Comment0( sbf_narg);
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n == EM_WSIZE)
+ {
+ f1= pop_float();
+ f2= pop_float();
+ f3= alloc_float();
+ "fsubs $f2, $f1, $f3";
+ free_reg(f1);
+ free_reg(f2);
+ push_reg(f3);
+ }
+ else if (n == EM_DSIZE)
+ {
+ f1= pop_double(NULL);
+ f2= pop_double(NULL);
+ f3= alloc_double(NULL);
+ "fsubd $f2, $f1, $f3";
+ free_double_reg(f1);
+ free_double_reg(f2);
+ push_double_reg(f3);
+ }
+ else
+ arg_error ("unimp sbf", n);
+ }
+ else
+ not_implemented ("sbf_narg");
+ }.
+
+C_mlf ==>
+ {
+ Comment( mlf, $1);
+ push_const($1);
+ C_mlf_narg();
+ }.
+
+C_mlf_narg ==>
+ {
+ reg_t f1;
+ reg_t f2;
+ reg_t f3;
+ int n;
+
+ Comment0( mlf_narg);
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n == EM_WSIZE)
+ {
+ f1= pop_float();
+ f2= pop_float();
+ f3= alloc_float();
+ "fmuls $f2, $f1, $f3";
+ free_reg(f1);
+ free_reg(f2);
+ push_reg(f3);
+ }
+ else if (n == EM_DSIZE)
+ {
+ f1= pop_double(NULL);
+ f2= pop_double(NULL);
+ f3= alloc_double(NULL);
+ "fmuld $f2, $f1, $f3";
+ free_double_reg(f1);
+ free_double_reg(f2);
+ push_double_reg(f3);
+ }
+ else
+ arg_error ("unimp mlf", n);
+ }
+ else
+ not_implemented ("mlf_narg");
+ }.
+
+C_dvf ==>
+ {
+ Comment( dvf, $1);
+ push_const($1);
+ C_dvf_narg();
+ }.
+
+C_dvf_narg ==>
+ {
+ reg_t f1;
+ reg_t f2;
+ reg_t f3;
+ int n;
+
+ Comment0( dvf_narg);
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n == EM_WSIZE)
+ {
+ f1= pop_float();
+ f2= pop_float();
+ f3= alloc_float();
+ "fdivs $f2, $f1, $f3";
+ free_reg(f1);
+ free_reg(f2);
+ push_reg(f3);
+ }
+ else if (n == EM_DSIZE)
+ {
+ f1= pop_double(NULL);
+ f2= pop_double(NULL);
+ f3= alloc_double(NULL);
+ "fdivd $f2, $f1, $f3";
+ free_double_reg(f1);
+ free_double_reg(f2);
+ push_double_reg(f3);
+ }
+ else
+ arg_error ("unimp dvf", n);
+ }
+ else
+ not_implemented ("dvf_narg");
+ }.
+
+C_ngf ==>
+ {
+ Comment( ngf, $1);
+ push_const($1);
+ C_ngf_narg();
+ }.
+
+C_ngf_narg ==>
+ {
+ reg_t f1;
+ reg_t f2;
+ int n;
+
+ Comment0( ngf_narg);
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n == EM_WSIZE || n == EM_DSIZE)
+ {
+ f1= pop_float();
+ f2= alloc_float();
+ "fnegs $f1, $f2";
+ free_reg(f1);
+ push_reg(f2);
+ }
+ else
+ arg_error ("unimp ngf", n);
+ }
+ else
+ not_implemented ("ngf_narg");
+ }.
+
+C_fif ==>
+ Comment( fif, $1);
+ push_const($1);
+ C_fif_narg().
+
+C_fif_narg ==>
+ {
+ int n;
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+
+ Comment0( fif_narg );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+
+ if (n==4)
+ {
+ "! unimplemented fif 4";
+ "st %g0, [%g0]"; /* unimp */
+ }
+ else if (n==8)
+ {
+ flush_cache();
+ "call fif8";
+ "nop";
+ }
+ else
+ arg_error ("fif", n);
+ }
+ else
+ {
+ a= alloc_reg();
+ flush_cache();
+ force_alloc_output();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= pop_reg();
+ "cmp 8, $d";
+ "be 8f";
+ "nop";
+ "cmp 4, $d";
+ "bne 0f";
+ "nop";
+ "4:";
+ "! unimplemented fif 4";
+ "st %g0, [%g0]";
+ "b 1f";
+ "0:";
+ "set EILLINS, $reg_o0";
+ "call trp";
+ "nop";
+ "b 1f";
+ "8:";
+ "call fif8";
+ "nop";
+ "1:";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_output();
+ }
+ }.
+
+
+C_fef ==>
+ Comment( fef, $1);
+ push_const($1);
+ C_fef_narg().
+
+C_fef_narg ==>
+ {
+ int n;
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ reg_t e;
+
+ Comment0( fef_narg );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+
+ if (n==4)
+ {
+ "! unimplemented fef 4";
+ "st %g0, [%g0]"; /* unimp */
+ }
+ else if (n==8)
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ e= alloc_reg();
+ "srl $a, 20, $b";
+ "and $b, 0x7ff, $c";
+ "dec 0x3fe, $c";
+ "set 0x7ff00000, $b";
+ "andn $a, $b, $d";
+ "set 0x3fe00000, $b";
+ "or $d, $b, $e";
+ push_reg(e);
+ push_reg(c);
+ free_reg(a);
+ free_reg(b);
+ free_reg(d);
+ }
+ else
+ arg_error ("fef", n);
+ }
+ else
+ {
+ a= alloc_reg();
+ flush_cache();
+ force_alloc_output();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= pop_reg();
+ "cmp 8, $d";
+ "be 8f";
+ "nop";
+ "cmp 4, $d";
+ "bne 0f";
+ "nop";
+ "4:";
+ "! unimplemented fef 4";
+ "st %g0, [%g0]";
+ "b 1f";
+ "0:";
+ "set EILLINS, $reg_o0";
+ "call trp";
+ "nop";
+ "b 1f";
+ "8:";
+ "ld [$reg_sp], $a";
+ "srl $a, 20, $b";
+ "and $b, 0x7ff, $c";
+ "dec 0x3fe, $c";
+ "dec STACK_CLICK, $reg_sp";
+ "st $c, [$reg_sp]";
+ "set 0x7ff00000, $c";
+ "andn $a, $c, $a";
+ "set 0x3fe00000, $c";
+ "or $a, $c, $a";
+ "st $a, [$reg_sp+STACK_CLICK]";
+ "1:";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_output();
+ }
+ }.
+
+/******************************************************************************/
+/* */
+/* Group 6 : Pointer arithmetic */
+/* */
+/******************************************************************************/
+
+C_adp ==>
+ Comment( adp , $1 );
+ inc_tos($1).
+
+C_ads
+ $1 == 4 ==>
+ Comment( ads , $1 );
+ if ((type_of_tos()) == T_cst) {
+ arith n;
+
+ n = pop_const(NULL);
+ inc_tos(n);
+ } else {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ a = pop_reg();
+ inc_tos_reg(a);
+ }.
+ default ==>
+ arg_error( "ads", $1).
+
+narg4(ads)
+
+C_sbs
+ $1 == 4 ==>
+ Comment( sbs , $1 );
+
+ if ((type_of_tos()) == T_cst) {
+ arith n;
+
+ n = pop_const(NULL);
+ inc_tos(-n);
+ } else {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ a = pop_reg();
+ b = pop_reg();
+ c = alloc_reg();
+ "sub $b, $a, $c";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }.
+ default ==>
+ arg_error( "sbs", $1).
+
+narg4(sbs)
+
+/******************************************************************************/
+/* */
+/* Group 7 : Increment/decrement/zero */
+/* */
+/******************************************************************************/
+
+C_inc ==>
+ Comment0( inc );
+ inc_tos(1).
+
+C_inl ==>
+ Comment( inl , $1 );
+ {
+ reg_t S1;
+
+ if (S1 = find_local($1, NULL)) {
+ change_reg(S1);
+ "inc 1, $S1";
+ } else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ C_loi(4);
+ C_inc();
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ C_sti(4);
+ }
+ }.
+
+C_ine.. ==>
+ {
+ char *ename;
+ const_str_t evalue;
+ reg_t a;
+ reg_t b;
+
+ Comment2( ine.. , $1, $2 );
+ a= alloc_reg();
+ b= alloc_reg();
+
+ ename= $1;
+ sprintf(evalue, "%d", $2);
+ "sethi %hi($ename+$evalue), $a";
+ "ld [$a+%lo($ename+$evalue)], $b";
+ "inc $b";
+ "st $b, [$a+%lo($ename+$evalue)]"
+ free_reg(a);
+ free_reg(b);
+ }.
+
+
+C_dec ==>
+ Comment0( dec );
+ inc_tos(-1).
+
+C_del ==>
+ Comment( del , $1 );
+ {
+ reg_t S1;
+
+ if (S1 = find_local($1, NULL)) {
+ change_reg(S1);
+ "dec 1, $S1";
+ } else {
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ C_loi(4);
+ C_dec();
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ C_sti(4);
+ }
+ }.
+
+C_dee.. ==>
+ {
+ char *ename;
+ const_str_t evalue;
+ reg_t a;
+ reg_t b;
+
+ Comment2( dee.. , $1, $2 );
+ a= alloc_reg();
+ b= alloc_reg();
+
+ ename= $1;
+ sprintf(evalue, "%d", $2);
+ "sethi %hi($ename+$evalue), $a";
+ "ld [$a+%lo($ename+$evalue)], $b";
+ "dec $b";
+ "st $b, [$a+%lo($ename+$evalue)]"
+ free_reg(a);
+ free_reg(b);
+ }.
+
+C_zrl ==>
+ Comment( zrl , $1 );
+ {
+ reg_t S1;
+
+ if (S1 = find_local($1, NULL)) {
+ change_reg(S1);
+ "mov 0, $S1";
+ } else {
+ push_const(0);
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb);
+ inc_tos($1);
+ C_sti(4);
+ }
+ }.
+
+C_zre.. ==>
+ {
+ char *ename;
+ const_str_t evalue;
+ reg_t a;
+
+ Comment2( zre.. , $1, $2 );
+ a= alloc_reg();
+
+ ename= $1;
+ sprintf(evalue, "%d", $2);
+ "sethi %hi($ename+$evalue), $a";
+ "st %g0, [$a+%lo($ename+$evalue)]"
+ free_reg(a);
+ }.
+
+C_zrf ==>
+ Comment( zrf , $1 );
+ push_const($1);
+ C_zrf_narg().
+
+C_zrf_narg ==>
+ Comment0( zrf_narg );
+ C_zer_narg().
+
+
+C_zer ==>
+ Comment( zer, $1);
+ push_const($1);
+ C_zer_narg().
+
+C_zer_narg ==>
+ {
+ reg_t a;
+ int n;
+ const_str_t n_str;
+
+ Comment0( zer_narg);
+
+ if (type_of_tos() == T_cst && top_const() <= 8)
+ {
+ n= pop_const(n_str);
+ if (n == 4)
+ push_const(0);
+ else if (n == 8)
+ {
+ push_const(0);
+ push_const(0);
+ }
+ else
+ arg_error ("zer", n);
+ }
+ else
+ {
+ a= pop_reg();
+ flush_cache();
+ "sub $reg_sp, $a, $reg_sp";
+ "1:"
+ "deccc 4, $a"; /* hack */
+ "st %g0, [$reg_sp+$a]";
+ "bne 1b";
+ "nop";
+ free_reg(a);
+ }
+ }.
+
+/******************************************************************************/
+/* */
+/* Group 8 : Convert */
+/* */
+/******************************************************************************/
+
+/* cii, ciu, cuu, cui are assumed to be called with legal arguments only */
+
+C_cii ==>
+ {
+ reg_t a; /* target obj size */
+ reg_t b; /* src obj size */
+ int n1; /* target obj size */
+ int n2; /* src obj size */
+ const_str_t n1_str;
+
+ Comment0( cii );
+ a= NULL;
+ b= NULL;
+
+ if (type_of_tos() != T_cst)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ }
+ else
+ {
+ n1= pop_const(n1_str);
+ if (type_of_tos() != T_cst)
+ {
+ a= alloc_reg();
+ "set $n1_str, $a";
+ b= pop_reg();
+ }
+ else
+ n2= pop_const(NULL);
+ }
+
+ if (!a)
+ {
+ a = pop_reg();
+ if (n1 > EM_WSIZE)
+ arg_error ("unimp cii", n1);
+ if (n2 > EM_WSIZE)
+ arg_error ("unimp cii", n2);
+ if (n2 < EM_WSIZE) {
+ b = alloc_reg();
+ if (n2 == 1)
+ {
+ "sll $a, 24, $b";
+ "sra $b, 24, $b";
+ }
+ else if (n2 == 2)
+ {
+ "sll $a, 16, $b";
+ "sra $b, 16, $b";
+ }
+ free_reg(a);
+ push_reg(b);
+ }
+ else
+ push_reg(a);
+ } else {
+ flush_cache();
+ "cmp $a, $b";
+ "ble 4f";
+ "nop"; /* delay slot */
+ "cmp $b, 1";
+ "bne 2f";
+ "nop"; /* delay slot */
+ "1:";
+ "b 3f";
+ "ldsb [$reg_sp+3], $a"; /* delay slot */
+ "2:"
+ "ldsh [$reg_sp+2], $a";
+ "3:";
+ "st $a, [$reg_sp]";
+ "4:";
+ free_reg(a);
+ free_reg(b);
+ }
+ }.
+
+
+C_cuu ==>
+ Comment0( cuu );
+ pop_nop(2).
+
+C_ciu ==>
+ Comment0( ciu );
+ pop_nop(2).
+
+C_cui ==>
+ Comment0( cui );
+ pop_nop(2).
+
+C_cfi ==>
+ {
+ reg_t a; /* target (int) size */
+ reg_t b; /* src (float) size */
+ reg_t s1;
+ reg_t s2;
+ reg_t d1;
+ reg_t d2;
+ int n1; /* target (int) size */
+ int n2; /* src (float) size */
+ const_str_t n1_str;
+
+ Comment0( cfi );
+ a= NULL;
+ b= NULL;
+ if (type_of_tos() != T_cst)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ }
+ else
+ {
+ n1= pop_const (n1_str);
+ if (type_of_tos() != T_cst)
+ {
+ a= alloc_reg();
+ "set $n1_str, $a";
+ b= pop_reg();
+ }
+ else
+ n2= pop_const(NULL);
+ }
+
+ if (!a)
+ {
+ if (n1 != EM_WSIZE)
+ arg_error ("unimp cfi", n1);
+ if (n2 == EM_WSIZE)
+ {
+ s1= pop_float();
+ d1= alloc_float();
+ "fstoi $s1, $d1";
+ free_reg(s1);
+ push_reg(d1);
+ }
+ else if (n2 == EM_DSIZE)
+ {
+ s1= pop_double(NULL);
+ d1= alloc_float();
+ "fdtoi $s1, $d1";
+ free_double_reg(s1);
+ push_reg(d1);
+ }
+ else
+ arg_error ("unimp cfi", n2);
+ }
+ else
+ {
+
+ d1= alloc_float();
+ flush_cache();
+ force_alloc_output();
+ "cmp $a, 4";
+ "bne 0f";
+ "nop";
+ "cmp $b, 4";
+ "be 4f";
+ "nop";
+ "cmp $b, 8";
+ "bne 0f";
+ "nop";
+ "8:";
+ "ld [$reg_sp], %f0";
+ "ld [$reg_sp+STACK_CLICK], %f1";
+ "fdtoi %f0, $d1";
+ "b 1f";
+ "inc 2*STACK_CLICK, $reg_sp"; /* delay slot */
+ "4:";
+ "ld [$reg_sp+2*STACK_CLICK], %f0";
+ "fstoi %f0, $d1";
+ "b 1f";
+ "inc STACK_CLICK, $reg_sp"; /* delay slot */
+ "0:";
+ "set E_EM_CFI, %o0";
+ "call trp";
+ "nop";
+ "1:";
+ free_reg(a);
+ free_reg(b);
+ push_reg(d1);
+ free_output();
+ }
+ }.
+
+C_cfu ==>
+ Comment0( cfu );
+ C_cfi().
+
+C_cff ==>
+ {
+ reg_t a; /* target (int) size */
+ reg_t b; /* src (float) size */
+ int n1; /* target (int) size */
+ int n2; /* src (float) size */
+ const_str_t n1_str;
+
+ Comment0( cff );
+ a= NULL;
+ b= NULL;
+ if (type_of_tos() != T_cst)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ }
+ else
+ {
+ n1= pop_const (n1_str);
+ if (type_of_tos() != T_cst)
+ {
+ a= alloc_reg();
+ "set $n1_str, $a";
+ b= pop_reg();
+ }
+ else
+ n2= pop_const(NULL);
+ }
+
+ if (!a)
+ {
+ if (n1 == EM_WSIZE)
+ {
+ if (n2 == EM_DSIZE)
+ {
+ a= pop_double(NULL);
+ b= alloc_float();
+ "fdtos $a, $b";
+ free_double_reg(a);
+ push_reg(b);
+ } else if (n2 != EM_WSIZE)
+ arg_error ("unimp cff", n2);
+ }
+ else if (n1 == EM_DSIZE)
+ {
+ if (n2 == EM_WSIZE)
+ {
+ a= pop_float();
+ b= alloc_double(NULL);
+ "fstod $a, $b";
+ free_reg(a);
+ push_double_reg(b);
+ } else if (n2 != EM_DSIZE)
+ arg_error ("unimp cff", n2);
+ }
+ else
+ arg_error ("unimp cff", n1);
+ }
+ else
+ {
+
+ flush_cache();
+ force_alloc_output();
+ "cmp $b, $a";
+ "be 1f";
+ "nop"; /* delay slot */
+ "cmp $b, 4";
+ "be 4f";
+ "nop";
+ "cmp $b, 8";
+ "be 8f";
+ "nop";
+ "0:"
+ "set E_EM_CFF, %o0";
+ "call trp";
+ "nop";
+ "4:";
+ "cmp $a, 8";
+ "bne 0b";
+ "nop";
+ "ld [$reg_sp], %f0";
+ "fstod %f0, %f2";
+ "dec STACK_CLICK, $reg_sp";
+ "st %f2, [$reg_sp]";
+ "st %f3, [$reg_sp+STACK_CLICK]";
+ "b 1f";
+ "nop";
+ "8:";
+ "cmp $a, 4";
+ "bne 0b";
+ "nop";
+ "ld [$reg_sp], %f0";
+ "ld [$reg_sp+STACK_CLICK], %f1";
+ "fdtos %f0, %f2";
+ "inc STACK_CLICK, $reg_sp";
+ "st %f2, [$reg_sp]";
+ "1:";
+ free_reg(a);
+ free_reg(b);
+ free_output();
+ }
+ }.
+
+C_cif ==>
+ {
+ reg_t a; /* target (float) size */
+ reg_t b; /* src (int) size */
+ int n1; /* target (float) size */
+ int n2; /* src (int) size */
+ reg_t r1;
+ reg_t f1;
+ const_str_t n1_str;
+
+ Comment0( cif );
+ a= NULL;
+ b= NULL;
+ if (type_of_tos() != T_cst)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ }
+ else
+ {
+ n1= pop_const (n1_str);
+ if (type_of_tos() != T_cst)
+ {
+ a= alloc_reg();
+ "set $n1_str, $a";
+ b= pop_reg();
+ }
+ else
+ n2= pop_const(NULL);
+ }
+
+ if (!a)
+ {
+ if (n2 != EM_WSIZE)
+ arg_error ("unimp cif", n2);
+ else
+ {
+ if (n1 == EM_WSIZE)
+ {
+ r1= pop_float();
+ f1= alloc_float();
+ "fitos $r1, $f1";
+ free_reg(r1);
+ push_reg(f1);
+
+ }
+ else if (n1 == EM_DSIZE)
+ {
+ r1= pop_float();
+ f1= alloc_double(NULL);
+ "fitod $r1, $f1";
+ free_reg(r1);
+ push_double_reg(f1);
+ }
+ else
+ arg_error ("unimp cif", n1);
+ }
+ }
+ else
+ {
+ flush_cache();
+ force_alloc_output();
+ "cmp $a, 4";
+ "be 4f";
+ "nop"; /* delay slot */
+ "cmp $a, 8";
+ "be 8f";
+ "nop"; /* delay slot */
+ "1:"
+ "set E_EM_CUF, %o0";
+ "call trp";
+ "nop";
+ "4:";
+ "cmp $b, 4";
+ "bne 1b";
+ "nop"; /* delay slot */
+ "ld [$reg_sp], %f0";
+ "fitos %f0, %f1";
+ "b 0f";
+ "st %f1, [$reg_sp]"; /* delay slot */
+ "8:";
+ "dec STACK_CLICK, $reg_sp";
+ "cmp $b, 4";
+ "bne 1b";
+ "nop"; /* delay slot */
+ "ld [$reg_sp+STACK_CLICK], %f0";
+ "fitod %f0, %f2";
+ "st %f2, [$reg_sp]";
+ "b 0f";
+ "st %f3, [$reg_sp+STACK_CLICK]"; /* delay slot */
+ "0:";
+ free_reg(a);
+ free_reg(b);
+ free_output();
+ }
+ }.
+
+
+C_cuf ==>
+ {
+ reg_t a; /* target (float) size */
+ reg_t b; /* src (int) size */
+ reg_t c;
+ reg_t fs1;
+ reg_t fs2;
+ reg_t fd1;
+ reg_t fd2;
+ int n1; /* target (float) size */
+ int n2; /* src (int) size */
+ const_str_t n1_str;
+
+ Comment0( cuf );
+ a= NULL;
+ b= NULL;
+ if (type_of_tos() != T_cst)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ }
+ else
+ {
+ n1= pop_const (n1_str);
+ if (type_of_tos() != T_cst)
+ {
+ a= alloc_reg();
+ "set $n1_str, $a";
+ b= pop_reg();
+ }
+ else
+ n2= pop_const(NULL);
+ }
+
+ if (!a)
+ {
+ if (n2 != EM_WSIZE)
+ arg_error ("unimp cuf", n2);
+ else
+ {
+ if (n1 == EM_WSIZE)
+ {
+ fs1= pop_float();
+ fs2= alloc_float();
+ a= alloc_reg();
+ "fitos $fs1, $fs2";
+ "sethi %hi(Fs0), $a";
+ "ld [$a+%lo(Fs0)], $fs1";
+ "fcmpes $fs2, $fs1";
+ "nop";
+ "fbge 0f";
+ "nop";
+ "sethi %hi(Fs80000000), $a";
+ "ld [$a+%lo(Fs80000000)], $fs1";
+ "fadds $fs1, $fs2, $fs2";
+ "0:";
+ push_reg(fs2);
+ free_reg(fs1);
+ free_reg(a);
+ }
+ else if (n1 == EM_DSIZE)
+ {
+ fs1= pop_float();
+ fd1= alloc_double(NULL);
+ fd2= alloc_double(NULL);
+ a= alloc_reg();
+ "fitod $fs1, $fd2";
+ "sethi %hi(Fd0), $a";
+ "ldd [$a+%lo(Fd0)], $fd1";
+ "fcmped $fd2, $fd1";
+ "nop";
+ "fbge 0f";
+ "nop";
+ "sethi %hi(Fd80000000), $a";
+ "ldd [$a+%lo(Fd80000000)], $fd1";
+ "faddd $fd1, $fd2, $fd2";
+ "0:";
+ free_reg(fs1);
+ free_double_reg(fd1);
+ push_double_reg(fd2);
+ free_reg(a);
+ }
+ else
+ arg_error ("unimp cuf", n1);
+ }
+ }
+ else
+ {
+#if 0
+ flush_cache();
+
+ "cmp $a, 4";
+ "be 4f";
+ "nop"; /* delay slot */
+ "cmp $a, 8";
+ "be 8f";
+ "nop"; /* delay slot */
+ "1:"
+ "set E_EM_CUF, %o0";
+ "set fatal, %g1";
+ "jmp %g1";
+ "nop";
+ "4:";
+ "cmp $b, 4";
+ "bne 1b";
+ "nop"; /* delay slot */
+ "ld [$reg_sp], $c";
+ "tst $c";
+ "bl 5f";
+ "nop"; /* delay slot */
+ "ld [$reg_sp], %f0";
+ "fitos %f0, %f1";
+ "b 0f";
+ "st %f1, [$reg_sp]"; /* delay slot */
+ "5:";
+ "set MAX_INT, $b";
+ "sub $c, $b, $a";
+ "st $a, [$reg_sp]";
+ "ld [$reg_sp], %f0";
+ "st $b, [$reg_sp]";
+ "ld [$reg_sp], %f1";
+ "fitos %f0, %f2";
+ "fitos %f1, %f3";
+ "fadds %f2, %f3, %f0";
+ "b 0f";
+ "st %f0, [$reg_sp]"; /* delay slot */
+ "8:";
+ "dec STACK_CLICK, $reg_sp";
+ "cmp $b, 4";
+ "bne 1b";
+ "nop"; /* delay slot */
+ "ld [$reg_sp+STACK_CLICK], $c";
+ "tst $c";
+ "bl 9f";
+ "nop"; /* delay slot */
+ "ld [$reg_sp+STACK_CLICK], %f0";
+ "fitod %f0, %f2";
+ "st %f2, [$reg_sp]";
+ "b 0f";
+ "st %f3, [$reg_sp+STACK_CLICK]"; /* delay slot */
+ "9:";
+ "set MAX_INT, $b";
+ "sub $c, $b, $a";
+ "st $a, [$reg_sp+STACK_CLICK]";
+ "ld [$reg_sp+STACK_CLICK], %f0";
+ "st $b, [$reg_sp+STACK_CLICK]";
+ "ld [$reg_sp+STACK_CLICK], %f1";
+ "fitod %f0, %f2";
+ "fitod %f1, %f4";
+ "fadds %f2, %f4, %f0";
+ "st %f0, [$reg_sp]";
+ "b 0f";
+ "st %f1, [$reg_sp+STACK_CLICK]"; /* delay slot */
+ "0:";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+#else
+ not_implemented ("cuf");
+#endif
+ }
+ }.
+/******************************************************************************/
+/* */
+/* Group 9 : Logical */
+/* */
+/******************************************************************************/
+
+C_and ==>
+ Comment( and, $1);
+ push_const($1);
+ C_and_narg().
+
+C_and_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ reg_t e;
+ reg_t f;
+ const_str_t a_cst_str;
+ const_str_t b_cst_str;
+ const_str_t c_cst_str;
+ const_str_t d_cst_str;
+ int n;
+ const_str_t n_str;
+
+ Comment0( and_narg );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(n_str);
+ if (n == EM_WSIZE)
+ {
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ a= NULL;
+ pop_const (a_cst_str);
+ }
+ else
+ a= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ b= NULL;
+ pop_const (b_cst_str);
+ }
+ else
+ b= pop_reg();
+ if (!a && !b)
+ {
+ a= alloc_reg();
+ "mov $a_cst_str, $a";
+ }
+ c= alloc_reg();
+ if (a)
+ if (b)
+ "and $a, $b, $c";
+ else
+ "and $a, $b_cst_str, $c";
+ else
+ "and $b, $a_cst_str, $c";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }
+ else if (n == EM_DSIZE)
+ {
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ a= NULL;
+ pop_const (a_cst_str);
+ }
+ else
+ a= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ b= NULL;
+ pop_const (b_cst_str);
+ }
+ else
+ b= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ c= NULL;
+ pop_const (c_cst_str);
+ }
+ else
+ c= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ d= NULL;
+ pop_const (d_cst_str);
+ }
+ else
+ d= pop_reg();
+ if (!b && !d)
+ {
+ b= alloc_reg();
+ "mov $b_cst_str, $b";
+ }
+ e= alloc_reg();
+ if (b)
+ if (d)
+ "and $b, $d, $e";
+ else
+ "and $b, $d_cst_str, $e";
+ else
+ "and $d, $b_cst_str, $e";
+ free_reg(b);
+ free_reg(d);
+ push_reg(e);
+ if (!a && !c)
+ {
+ a= alloc_reg();
+ "mov $a_cst_str, $a";
+ }
+ e= alloc_reg();
+ if (a)
+ if (c)
+ "and $a, $c, $e";
+ else
+ "and $a, $c_cst_str, $e";
+ else
+ "and $c, $a_cst_str, $e";
+ free_reg(a);
+ free_reg(c);
+ push_reg(e);
+ }
+ else if (!(n % EM_WSIZE))
+ {
+ a= alloc_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ e= alloc_reg();
+ f= alloc_reg();
+ flush_cache();
+
+ "set $n_str, $a";
+ "add $reg_sp, $a, $b";
+ "mov $a, $c";
+ "1:";
+ "deccc 4, $c";
+ "ld [$reg_sp+$c], $d";
+ "ld [$b+$c], $e";
+ "and $d, $e, $f";
+ "bnz 1b";
+ "st $f, [$b+$c]"; /* delay slot */
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_reg(e);
+ free_reg(f);
+ }
+ else
+ arg_error ("unimp and", n);
+ }
+ else
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ e= alloc_reg();
+ f= alloc_reg();
+ flush_cache();
+
+ "add $reg_sp, $a, $b";
+ "mov $a, $c";
+ "1:";
+ "deccc 4, $c";
+ "ld [$reg_sp+$c], $d";
+ "ld [$b+$c], $e";
+ "and $d, $e, $f";
+ "bnz 1b";
+ "st $f, [$b+$c]"; /* delay slot */
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_reg(e);
+ free_reg(f);
+
+ }
+ }.
+
+C_ior ==>
+ Comment( ior, $1);
+ push_const($1);
+ C_ior_narg().
+
+C_ior_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ reg_t e;
+ reg_t f;
+ const_str_t a_cst_str;
+ const_str_t b_cst_str;
+ const_str_t c_cst_str;
+ const_str_t d_cst_str;
+ int n;
+ const_str_t n_str;
+
+ Comment0( ior_narg );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(n_str);
+ if (n == EM_WSIZE)
+ {
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ a= NULL;
+ pop_const (a_cst_str);
+ }
+ else
+ a= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ b= NULL;
+ pop_const (b_cst_str);
+ }
+ else
+ b= pop_reg();
+ if (!a && !b)
+ {
+ a= alloc_reg();
+ "mov $a_cst_str, $a";
+ }
+ c= alloc_reg();
+ if (a)
+ if (b)
+ "or $a, $b, $c";
+ else
+ "or $a, $b_cst_str, $c";
+ else
+ "or $b, $a_cst_str, $c";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }
+ else if (n == EM_DSIZE)
+ {
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ a= NULL;
+ pop_const (a_cst_str);
+ }
+ else
+ a= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ b= NULL;
+ pop_const (b_cst_str);
+ }
+ else
+ b= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ c= NULL;
+ pop_const (c_cst_str);
+ }
+ else
+ c= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ d= NULL;
+ pop_const (d_cst_str);
+ }
+ else
+ d= pop_reg();
+ if (!b && !d)
+ {
+ b= alloc_reg();
+ "mov $b_cst_str, $b";
+ }
+ e= alloc_reg();
+ if (b)
+ if (d)
+ "or $b, $d, $e";
+ else
+ "or $b, $d_cst_str, $e";
+ else
+ "or $d, $b_cst_str, $e";
+ free_reg(b);
+ free_reg(d);
+ push_reg(e);
+ if (!a && !c)
+ {
+ a= alloc_reg();
+ "mov $a_cst_str, $a";
+ }
+ e= alloc_reg();
+ if (a)
+ if (c)
+ "or $a, $c, $e";
+ else
+ "or $a, $c_cst_str, $e";
+ else
+ "or $c, $a_cst_str, $e";
+ free_reg(a);
+ free_reg(c);
+ push_reg(e);
+ }
+ else if (!(n % EM_WSIZE))
+ {
+ a= alloc_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ e= alloc_reg();
+ f= alloc_reg();
+ flush_cache();
+
+ "set $n_str, $a";
+ "add $reg_sp, $a, $b";
+ "mov $a, $c";
+ "1:";
+ "deccc 4, $c";
+ "ld [$reg_sp+$c], $d";
+ "ld [$b+$c], $e";
+ "or $d, $e, $f";
+ "bnz 1b";
+ "st $f, [$b+$c]"; /* delay slot */
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_reg(e);
+ free_reg(f);
+ }
+ else
+ arg_error ("unimp ior", n);
+ }
+ else
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ e= alloc_reg();
+ f= alloc_reg();
+ flush_cache();
+
+ "add $reg_sp, $a, $b";
+ "mov $a, $c";
+ "1:";
+ "deccc 4, $c";
+ "ld [$reg_sp+$c], $d";
+ "ld [$b+$c], $e";
+ "or $d, $e, $f";
+ "bnz 1b";
+ "st $f, [$b+$c]"; /* delay slot */
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_reg(e);
+ free_reg(f);
+ }
+ }.
+
+
+
+C_xor ==>
+ Comment( xor, $1);
+ push_const($1);
+ C_xor_narg().
+
+C_xor_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ reg_t e;
+ reg_t f;
+ const_str_t a_cst_str;
+ const_str_t b_cst_str;
+ const_str_t c_cst_str;
+ const_str_t d_cst_str;
+ int n;
+ const_str_t n_str;
+
+ Comment0( xor_narg );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(n_str);
+ if (n == EM_WSIZE)
+ {
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ a= NULL;
+ pop_const (a_cst_str);
+ }
+ else
+ a= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ b= NULL;
+ pop_const (b_cst_str);
+ }
+ else
+ b= pop_reg();
+ if (!a && !b)
+ {
+ a= alloc_reg();
+ "mov $a_cst_str, $a";
+ }
+ c= alloc_reg();
+ if (a)
+ if (b)
+ "xor $a, $b, $c";
+ else
+ "xor $a, $b_cst_str, $c";
+ else
+ "xor $b, $a_cst_str, $c";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }
+ else if (n == EM_DSIZE)
+ {
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ a= NULL;
+ pop_const (a_cst_str);
+ }
+ else
+ a= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ b= NULL;
+ pop_const (b_cst_str);
+ }
+ else
+ b= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ c= NULL;
+ pop_const (c_cst_str);
+ }
+ else
+ c= pop_reg();
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ d= NULL;
+ pop_const (d_cst_str);
+ }
+ else
+ d= pop_reg();
+ if (!b && !d)
+ {
+ b= alloc_reg();
+ "mov $b_cst_str, $b";
+ }
+ e= alloc_reg();
+ if (b)
+ if (d)
+ "xor $b, $d, $e";
+ else
+ "xor $b, $d_cst_str, $e";
+ else
+ "xor $d, $b_cst_str, $e";
+ free_reg(b);
+ free_reg(d);
+ push_reg(e);
+ if (!a && !c)
+ {
+ a= alloc_reg();
+ "mov $a_cst_str, $a";
+ }
+ e= alloc_reg();
+ if (a)
+ if (c)
+ "xor $a, $c, $e";
+ else
+ "xor $a, $c_cst_str, $e";
+ else
+ "xor $c, $a_cst_str, $e";
+ free_reg(a);
+ free_reg(c);
+ push_reg(e);
+ }
+ else if (!(n % EM_WSIZE))
+ {
+ a= alloc_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ e= alloc_reg();
+ f= alloc_reg();
+ flush_cache();
+
+ "set $n_str, $a";
+ "add $reg_sp, $a, $b";
+ "mov $a, $c";
+ "1:";
+ "deccc 4, $c";
+ "ld [$reg_sp+$c], $d";
+ "ld [$b+$c], $e";
+ "xor $d, $e, $f";
+ "bnz 1b";
+ "st $f, [$b+$c]"; /* delay slot */
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_reg(e);
+ free_reg(f);
+ }
+ else
+ arg_error ("unimp xor", n);
+ }
+ else
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ e= alloc_reg();
+ f= alloc_reg();
+ flush_cache();
+
+ "add $reg_sp, $a, $b";
+ "mov $a, $c";
+ "1:";
+ "deccc 4, $c";
+ "ld [$reg_sp+$c], $d";
+ "ld [$b+$c], $e";
+ "xor $d, $e, $f";
+ "bnz 1b";
+ "st $f, [$b+$c]"; /* delay slot */
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ free_reg(e);
+ free_reg(f);
+ }
+ }.
+
+
+
+C_com ==>
+ Comment( com, $1);
+ push_const($1);
+ C_com_narg().
+
+C_com_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ int n;
+ int i;
+ const_str_t i_str;
+
+ Comment0( com_narg );
+ if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
+ {
+ n= pop_const(NULL);
+ if (n == 4)
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ "not $a, $b";
+ free_reg(a);
+ push_reg(b);
+ }
+ else if (n == 8)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ "not $a, $c";
+ "not $b, $d";
+ push_reg(d);
+ push_reg(c);
+ free_reg(b);
+ free_reg(a);
+ }
+ else if (n>0 && !(n % 4))
+ {
+ flush_cache();
+ a= alloc_reg();
+ b= alloc_reg();
+ for (i= 0; i< n; i += 4)
+ {
+ sprintf(i_str, "%d", i);
+ "ld [$reg_sp+$i_str], $a";
+ "not $a, $b";
+ "st $b, [$reg_sp+$i_str]";
+ }
+ }
+ else
+ arg_error ("com", n);
+ }
+ else
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ flush_cache();
+ "1:";
+ "deccc 4, $a";
+ "ld [$reg_sp+$a], $b";
+ "not $a, $c";
+ "bnz 1b";
+ "st $c, [$reg_sp+$a";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ }
+ }.
+
+C_rol
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ int n;
+ const_str_t n_str;
+
+ Comment( rol, $1);
+
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n<0)
+ arg_error("rol 4:", n);
+ else
+ {
+ n= n % 32;
+ if (n)
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ sprintf(n_str, "%d", n);
+ "sll $a, $n_str, $b";
+ sprintf(n_str, "%d", 32-n);
+ "srl $a, $n_str, $c";
+ "or $b, $c, $a";
+ push_reg(a);
+ free_reg(b);
+ free_reg(c);
+ }
+ }
+ }
+ else
+ {
+ a= pop_reg();
+ b= pop_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ "and $a, 31, $c";
+ "mov 32, $a";
+ "sub $a, $c, $d";
+ "sll $b, $c, $a";
+ "srl $b, $d, $c";
+ "or $a, $c, $b";
+ free_reg(a);
+ push_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }.
+ default ==>
+ arg_error( "rol", $1).
+
+narg4(rol)
+
+C_ror
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ int n;
+ const_str_t n_str;
+
+ Comment( ror, $1);
+
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n<0)
+ arg_error("ror 4:", n);
+ else
+ {
+ n= n % 32;
+ if (n)
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ sprintf(n_str, "%d", n);
+ "srl $a, $n_str, $b";
+ sprintf(n_str, "%d", 32-n);
+ "sll $a, $n_str, $c";
+ "or $b, $c, $a";
+ push_reg(a);
+ free_reg(b);
+ free_reg(c);
+ }
+ }
+ }
+ else
+ {
+ a= pop_reg();
+ b= pop_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ "and $a, 31, $c";
+ "mov 32, $a";
+ "sub $a, $c, $d";
+ "srl $b, $c, $a";
+ "sll $b, $d, $c";
+ "or $a, $c, $b";
+ free_reg(a);
+ push_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }.
+ default ==>
+ arg_error( "ror", $1).
+
+narg4(ror)
+
+/******************************************************************************/
+/* */
+/* Group 10 : Sets */
+/* */
+/******************************************************************************/
+
+C_inn ==>
+ Comment( inn, $1);
+ push_const($1);
+ C_inn_narg().
+
+C_inn_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ int i;
+ int n;
+ const_str_t i_str;
+ const_str_t n_str;
+
+ Comment0(inn_narg);
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ n= pop_const(n_str);
+ if (n == EM_WSIZE)
+ {
+ if (type_of_tos() == T_cst)
+ {
+ i= pop_const (i_str);
+ if (i >= n*8)
+ push_const(0);
+ else
+ {
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ "srl $a, $i_str, $b";
+ "and $b, 1, $c";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }
+ }
+ else
+ {
+ a= pop_reg();
+ b= pop_reg();
+ c= alloc_reg();
+ "srl $b, $a, $c";
+ "and $c, 1, $a";
+ push_reg(a);
+ free_reg(b);
+ free_reg(c);
+ }
+ }
+ else if (n == 2*EM_WSIZE)
+ {
+ if (type_of_tos() == T_cst)
+ {
+ i= pop_const (i_str);
+ if (i >= n*8)
+ push_const(0);
+ else
+ {
+ if (i>= EM_WSIZE*8)
+ {
+ i -= EM_WSIZE*8;
+ pop_nop(1);
+ a= pop_reg();
+ }
+ else
+ {
+ a= pop_reg();
+ pop_nop(1);
+ }
+ b= alloc_reg();
+ c= alloc_reg();
+ "srl $a, $i_str, $b";
+ "and $b, 1, $c";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }
+ }
+ else
+ {
+ a= pop_reg();
+ flush_cache();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ flush_cache();
+ "andn $a, 31, $b";
+ "and $a, 31, $c";
+ "srl $b, 3, $d";
+ "ld [$reg_sp+$d], $b";
+ "inc $n_str, $reg_sp";
+ "srl $b, $c, $d";
+ "and $d, 1, $b";
+ free_reg(a);
+ push_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }
+ else if (n % EM_WSIZE)
+ arg_error ("inn", n);
+ else
+ {
+ a= pop_reg();
+ flush_cache();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ flush_cache();
+ "andn $a, 31, $b";
+ "and $a, 31, $c";
+ "srl $b, 3, $d";
+ "ld [$reg_sp+$d], $b";
+ "inc $n_str, $reg_sp";
+ "srl $b, $c, $d";
+ "and $d, 1, $b";
+ free_reg(a);
+ push_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }
+ else
+ arg_error ("inn_narg");
+ }.
+
+C_set ==> Comment( set, $1);
+ push_const($1);
+ C_set_narg().
+
+C_set_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ int n;
+ const_str_t n_str;
+
+ Comment0( set_narg );
+
+ if (type_of_tos() == T_cst) {
+ n = pop_const(n_str);
+ if (n == EM_WSIZE) {
+ b = alloc_reg();
+ c = alloc_reg();
+ a = pop_reg();
+ "set 1, $c";
+ "sll $c, $a, $b";
+ free_reg(a);
+ free_reg(c);
+ push_reg(b);
+ } else {
+ a= alloc_reg();
+ b= pop_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ flush_cache();
+ sprintf(n_str, "%d", n);
+ "set $n_str, $a";
+ "sub $reg_sp, $a, $reg_sp";
+ "1:";
+ "deccc 4, $a";
+ "bnz 1b";
+ "st %g0, [$reg_sp+$a]"; /* HACK delay */
+ "andn $b, 31, $c";
+ "and $b, 31, $b";
+ "srl $c, 3, $c";
+ "set 1, $a";
+ "sll $a, $b, $d";
+ "st $d, [$reg_sp+$c]";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ } else {
+ a= pop_reg();
+ b= pop_reg();
+ flush_cache();
+ c= alloc_reg();
+ d= alloc_reg();
+ "sub $reg_sp, $a, $reg_sp";
+ "1:";
+ "deccc 4, $a";
+ "bnz 1b";
+ "st %g0, [$reg_sp+$a]"; /* HACK delay */
+ "andn $b, 31, $c";
+ "and $b, 31, $b";
+ "srl $c, 3, $c";
+ "set 1, $a";
+ "sll $a, $b, $d";
+ "st $d, [$reg_sp+$c]";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }.
+
+
+/******************************************************************************/
+/* */
+/* Group 11 : Array */
+/* */
+/******************************************************************************/
+
+C_lar
+ ($1 == 4) ==>
+ Comment(lar, $1);
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ pop_reg_as(reg_o1);
+ pop_reg_as(reg_o2);
+ flush_cache();
+ "call lar";
+ "nop";
+ free_output().
+ default ==>
+ arg_error ("arg error lar", $1).
+
+narg4(lar)
+
+C_sar
+ ($1 == 4) ==>
+ Comment( sar , $1 );
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ pop_reg_as(reg_o1);
+ pop_reg_as(reg_o2);
+ flush_cache();
+ "call sar";
+ "nop"
+ free_output().
+ default ==>
+ arg_error ("arg error sar", $1).
+
+narg4(sar)
+
+C_aar
+ ($1 == 4) ==>
+ Comment(aar, $1);
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ pop_reg_as(reg_o1);
+ pop_reg_as(reg_o2);
+ flush_cache();
+ "call aar";
+ "nop";
+ soft_alloc_reg(reg_o0);
+ free_output();
+ push_reg(reg_o0).
+ default ==>
+ arg_error ("arg error aar", $1).
+
+narg4(aar)
+
+/******************************************************************************/
+/* */
+/* Group 12 : Compare */
+/* */
+/******************************************************************************/
+
+C_cmi
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ const_str_t d;
+
+ Comment( cmi, $1 );
+
+ if (type_of_tos() == T_cst && const13(top_const()))
+ {
+ pop_const(d);
+ a= pop_reg();
+ b= alloc_reg();
+ "cmp $a, $d";
+ "be,a 1f";
+ "mov 0, $b"; /* delay slot */
+ "bg,a 1f";
+ "mov 1, $b"; /* delay slot */
+ "mov -1, $b";
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }
+ else
+ {
+ a= pop_reg();
+ b= NULL;
+ c= alloc_reg();
+ if (type_of_tos() == T_cst)
+ {
+ pop_const(d);
+ "cmp $a, $d";
+ }
+ else
+ {
+ b= pop_reg();
+ "cmp $a, $b";
+ }
+ "be,a 1f";
+ "mov 0, $c"; /* delay slot */
+ "bg,a 1f";
+ "mov -1, $c"; /* delay slot */
+ "mov 1, $c";
+ "1:";
+ free_reg(a);
+ if (b)
+ free_reg(b);
+ push_reg(c);
+ }
+ }.
+ default ==>
+ arg_error ("unimp cmi", $1).
+
+narg4(cmi)
+
+C_cmu ==>
+ Comment( cmu, $1 );
+ push_const($1);
+ C_cmu_narg().
+
+C_cmu_narg ==>
+ {
+ int n;
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ const_str_t d;
+
+ Comment0( cmu_narg );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n != EM_WSIZE)
+ arg_error ("unimp cmu", n);
+ else
+ {
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ {
+ pop_const(d);
+ a= pop_reg();
+ b= alloc_reg();
+ "cmp $a, $d";
+ "be,a 1f";
+ "mov 0, $b"; /* delay slot */
+ "bgu,a 1f";
+ "mov 1, $b"; /* delay slot */
+ "mov -1, $b";
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }
+ else
+ {
+ a= pop_reg();
+ b= NULL;
+ c= alloc_reg();
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ {
+ pop_const(d);
+ "cmp $a, $d";
+ }
+ else
+ {
+ b= pop_reg();
+ "cmp $a, $b";
+ }
+ "be,a 1f";
+ "mov 0, $c"; /* delay slot */
+ "bgu,a 1f";
+ "mov -1, $c"; /* delay slot */
+ "mov 1, $c";
+ "1:";
+ free_reg(a);
+ if (b)
+ free_reg(b);
+ push_reg(c);
+ }
+ }
+ }
+ else
+ not_implemented ("cmu_narg");
+ }.
+
+C_cms ==>
+ Comment( cms, $1 );
+ push_const($1);
+ C_cms_narg().
+
+C_cms_narg ==>
+ {
+ int n;
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ reg_t e;
+ const_str_t b_str;
+ const_str_t n_str;
+
+ Comment0( cms_narg );
+ if (type_of_tos() == T_cst && top_const() <= EM_WSIZE)
+ {
+ n= pop_const(n_str);
+ if (n == EM_WSIZE)
+ {
+ b= NULL;
+ c= alloc_reg();
+ if (type_of_tos() == T_cst)
+ {
+ pop_const(b_str);
+ a= pop_reg();
+ "cmp $a, $b_str";
+ }
+ else
+ {
+ a= pop_reg();
+ b= pop_reg();
+ "cmp $a, $b";
+ }
+ "be,a 1f";
+ "mov 0, $c";
+ "mov 1, $c";
+ "1:";
+ free_reg(a);
+ if (b)
+ free_reg(b);
+ push_reg(c);
+ }
+ else if (n % EM_WSIZE)
+ arg_error ("unimp cms", n);
+ }
+ else
+ {
+ a= pop_reg();
+ flush_cache();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+
+ "add $reg_sp, $a, $b";
+ "dec 4, $b";
+ "1:";
+ "ld [$b], $c";
+ "ld [$b+$a], $d";
+ "cmp $d, $c";
+ "bne,a 2f";
+ "mov 1, $b"; /* delay slot */
+ "cmp $b, $reg_sp";
+ "bg 1b";
+ "dec 4, $b"; /* delay slot */
+ "mov 0, $b";
+ "2:";
+ "add $reg_sp, $a, $reg_sp";
+ "add $reg_sp, $a, $reg_sp";
+
+ free_reg(a);
+ push_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }.
+
+C_cmp ==>
+ Comment0( cmp );
+ C_cmu( (arith)4).
+
+C_tlt ==>
+ Comment0( tlt );
+ {
+ reg_t a;
+ reg_t b;
+
+ a = pop_reg();
+ b= alloc_reg();
+ " tst $a";
+ " bl,a 1f";
+ " mov 1, $b"; /* delay slot */
+ " set 0, $b";
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }.
+
+C_tle ==>
+ Comment0( tle );
+ {
+ reg_t a;
+ reg_t b;
+
+ a = pop_reg();
+ b= alloc_reg();
+ "tst $a";
+ "ble,a 1f";
+ "mov 1, $b"; /* delay slot */
+ "set 0, $b";
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }.
+
+C_tge ==>
+ Comment0( tge );
+ {
+ reg_t a;
+ reg_t b;
+
+ a = pop_reg();
+ b = alloc_reg();
+ " tst $a";
+ " bge,a 1f";
+ " mov 1, $b"; /* delay slot */
+ " set 0, $b";
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }.
+
+C_tgt ==>
+ Comment0( tgt );
+ {
+ reg_t a;
+ reg_t b;
+
+ a = pop_reg();
+ b = alloc_reg();
+ " tst $a";
+ " bg,a 1f";
+ " mov 1, $b"; /* delay slot */
+ " set 0, $b";
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }.
+
+C_tne ==>
+ Comment0( tne );
+ {
+ reg_t a;
+ reg_t b;
+
+ a = pop_reg();
+ b = alloc_reg();
+ " tst $a";
+ " bne,a 1f";
+ " mov 1, $b"; /* delay slot */
+ " set 0, $b"; /* sup optimal */
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }.
+
+C_teq ==>
+ Comment0( teq );
+ {
+ reg_t a;
+ reg_t b;
+
+ a = pop_reg();
+ b = alloc_reg();
+ " tst $a";
+ " be,a 1f";
+ " mov 1, $b"; /* delay slot */
+ " set 0, $b";
+ "1:";
+ free_reg(a);
+ push_reg(b);
+ }.
+C_cmf ==>
+ Comment( cmf, $1);
+ push_const($1);
+ C_cmf_narg().
+
+C_cmf_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ int n;
+
+ Comment0( cmf_narg);
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(NULL);
+ if (n == EM_FSIZE)
+ {
+ a= pop_float();
+ b= pop_float();
+ c= alloc_reg();
+ "fcmpes $b, $a";
+ "nop";
+ "fbe,a 1f";
+ "mov 0, $c";
+ "fbl,a 1f";
+ "mov -1, $c";
+ "mov 1, $c";
+ "1:";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }
+ else if (n == EM_DSIZE)
+ {
+ a= pop_double(NULL);
+ b= pop_double(NULL);
+ c= alloc_reg();
+ "fcmped $b, $a";
+ "nop";
+ "fbe,a 1f";
+ "mov 0, $c";
+ "fbl,a 1f";
+ "mov -1, $c";
+ "mov 1, $c";
+ "1:";
+ free_double_reg(a);
+ free_double_reg(b);
+ push_reg(c);
+ }
+ else
+ arg_error ("cmf", n);
+ }
+ else
+ not_implemented ("cmf_narg");
+ }.
+
+/******************************************************************************/
+/* */
+/* Group 13 : Branch */
+/* */
+/******************************************************************************/
+
+C_bra ==>
+ Comment( bra , $1 );
+ {
+ char *lbl;
+
+ flush_cache();
+ lbl = $1;
+ "b $lbl";
+ "nop"; /* delay slot */
+ }.
+
+C_bge ==>
+ Comment( bge , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+ reg_t b;
+ const_str_t n_str;
+
+ a= NULL;
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ pop_const(n_str);
+ else
+ a = pop_reg();
+ b = pop_reg();
+ flush_cache();
+ if (a)
+ "cmp $b, $a";
+ else
+ "cmp $b, $n_str";
+ "bge $lbl";
+ "nop" /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ }.
+
+C_bne ==>
+ Comment( bne , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+ reg_t b;
+ const_str_t n_str;
+
+ a= NULL;
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ pop_const(n_str);
+ else
+ a = pop_reg();
+ b = pop_reg();
+ flush_cache();
+ if (a)
+ "cmp $b, $a";
+ else
+ "cmp $b, $n_str";
+ "bne $lbl";
+ "nop" /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ }.
+
+C_beq ==>
+ Comment( beq , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+ reg_t b;
+ const_str_t n_str;
+
+ a= NULL;
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ pop_const(n_str);
+ else
+ a = pop_reg();
+ b = pop_reg();
+ flush_cache();
+ if (a)
+ "cmp $b, $a";
+ else
+ "cmp $b, $n_str";
+ "beq $lbl";
+ "nop" /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ }.
+
+C_ble ==>
+ Comment( ble , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+ reg_t b;
+ const_str_t n_str;
+
+ a= NULL;
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ pop_const(n_str);
+ else
+ a = pop_reg();
+ b = pop_reg();
+ flush_cache();
+ if (a)
+ "cmp $b, $a";
+ else
+ "cmp $b, $n_str";
+ "ble $lbl";
+ "nop" /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ }.
+
+C_blt ==>
+ Comment( blt , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+ reg_t b;
+ const_str_t n_str;
+
+ a= NULL;
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ pop_const(n_str);
+ else
+ a = pop_reg();
+ b = pop_reg();
+ flush_cache();
+ if (a)
+ "cmp $b, $a";
+ else
+ "cmp $b, $n_str";
+ "bl $lbl";
+ "nop" /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ }.
+
+C_bgt ==>
+ Comment( bgt , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+ reg_t b;
+ const_str_t n_str;
+
+ a= NULL;
+ if (type_of_tos() == T_cst &&
+ const13(top_const()))
+ pop_const(n_str);
+ else
+ a = pop_reg();
+ b = pop_reg();
+ flush_cache();
+ if (a)
+ "cmp $b, $a";
+ else
+ "cmp $b, $n_str";
+ "bg $lbl";
+ "nop" /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ }.
+
+C_zlt ==>
+ Comment( zlt , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+
+ a = pop_reg();
+ flush_cache();
+ "tst $a";
+ "bl $lbl";
+ "nop"; /* delay slot */
+ free_reg(a);
+ }
+ .
+
+C_zle ==>
+ Comment( zle , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+
+ a = pop_reg();
+ flush_cache();
+ "tst $a";
+ "ble $lbl";
+ "nop"; /* delay slot */
+ free_reg(a);
+ }
+ .
+
+C_zeq ==>
+ Comment( zeq , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+
+ a = pop_reg();
+ flush_cache();
+ "tst $a";
+ "be $lbl";
+ "nop"; /* delay slot */
+ free_reg(a);
+ }
+ .
+
+C_zne ==>
+ Comment( zne , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+
+ a = pop_reg();
+ flush_cache();
+ "tst $a";
+ "bne $lbl";
+ "nop"; /* delay slot */
+ free_reg(a);
+ }
+ .
+
+C_zge ==>
+ Comment( zge , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+
+ a = pop_reg();
+ flush_cache();
+ "tst $a";
+ "bge $lbl";
+ "nop"; /* delay slot */
+ free_reg(a);
+ }
+ .
+
+C_zgt ==>
+ Comment( zgt , $1 );
+ {
+ char *lbl = $1;
+ reg_t a;
+
+ a = pop_reg();
+ flush_cache();
+ "tst $a";
+ "bg $lbl";
+ "nop"; /* delay slot */
+ free_reg(a);
+ }
+ .
+/******************************************************************************/
+/* */
+/* Group 14 : Procedure call instructions */
+/* */
+/******************************************************************************/
+
+C_cai ==>
+ Comment0( cai );
+ {
+ reg_t a;
+
+ a= pop_reg();
+ flush_cache();
+ "call $a";
+ "nop"; /* delay slot */
+ free_reg(a);
+ }.
+
+C_cal ==>
+ Comment( cal , $1 );
+ {
+ char *lbl = $1;
+ flush_cache();
+ "call $lbl";
+ "nop"; /* delay slot */
+ }.
+
+C_lfr
+ $1 == 4 ==>
+ {
+ Comment( lfr , $1 );
+ forced_alloc_reg(RETL_LD);
+ push_reg(RETL_LD);
+ }.
+ $1 == 8 ==>
+ {
+ Comment( lfr , $1 );
+ forced_alloc_reg(RETL_LD);
+ forced_alloc_reg(RETH_LD);
+ push_reg(RETH_LD);
+ push_reg(RETL_LD);
+ }.
+ default ==>
+ arg_error( "lfr", $1).
+
+C_ret
+ $1 == 0 ==>
+ {
+ Comment( ret , $1 );
+ load_float_regs();
+ if (debug)
+ free_all_reg_vars();
+ "restore";
+ "retl";
+ "add %sp, $reg_gap, %sp";
+ if (debug)
+ alloc_all_reg_vars();
+ }.
+ $1 == 4 ==>
+ {
+ Comment( ret , $1 );
+ soft_alloc_reg(RETL_ST);
+ pop_reg_as(RETL_ST);
+ free_reg(RETL_ST);
+ load_float_regs();
+ if (debug)
+ free_all_reg_vars();
+ "restore";
+ "retl";
+ "add %sp, $reg_gap, %sp";
+ if (debug)
+ alloc_all_reg_vars();
+ }.
+ $1 == 8 ==>
+ {
+ Comment( ret , $1 );
+ soft_alloc_reg(RETL_ST);
+ soft_alloc_reg(RETH_ST);
+ pop_reg_as(RETL_ST);
+ pop_reg_as(RETH_ST);
+ free_reg(RETL_ST);
+ free_reg(RETH_ST);
+ load_float_regs();
+ if (debug)
+ free_all_reg_vars();
+ "restore";
+ "retl";
+ "add %sp, $reg_gap, %sp";
+ if (debug)
+ alloc_all_reg_vars();
+ }.
+ default ==>
+ arg_error( "ret", $1).
+
+/******************************************************************************/
+/* */
+/* Group 15 : Miscellaneous instructions */
+/* */
+/******************************************************************************/
+
+C_asp ==>
+ Comment( asp , $1 );
+ push_const($1);
+ C_ass(EM_WSIZE).
+
+
+C_ass
+ $1 == 4 ==>
+ {
+ int n;
+ const_str_t n_str;
+ reg_t a;
+
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(n_str);
+ if (n % EM_WSIZE)
+ arg_error ("asp", n);
+ else
+ if (n>=0)
+ pop_nop (n/4);
+ else
+ {
+ flush_cache();
+ if (const13(n))
+ "inc $n_str, $reg_sp";
+ else
+ {
+ a= alloc_reg();
+ "set $n_str, $a"
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ }
+ }
+ }
+ else
+ {
+ a= pop_reg();
+ flush_cache();
+ "add $reg_sp, $a, $reg_sp";
+ free_reg(a);
+ }
+ }.
+ default ==>
+ arg_error( "ass", $1).
+
+
+narg4(ass)
+
+C_blm ==>
+ Comment( blm, $1);
+ push_const($1);
+ C_bls (EM_WSIZE).
+
+C_bls
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ reg_t ao_reg;
+ reg_t bo_reg;
+ int n;
+ int i;
+ const_str_t n_str;
+ const_str_t ac_str;
+ const_str_t bc_str;
+
+ Comment( bls , $1 );
+ if (type_of_tos() == T_cst)
+ {
+ n= pop_const(n_str);
+ if (n % EM_WSIZE)
+ arg_error ("blm", n);
+ else if (n <= MAX_UNROLL)
+ {
+ c= alloc_reg();
+ for (i=0; i<n; i += EM_WSIZE)
+ {
+ if (type_of_tos() & T_reg2) /* dest */
+ a= pop_reg_reg (&ao_reg);
+ else
+ {
+ ao_reg= NULL;
+ a= pop_reg_c13(ac_str);
+ }
+ if (type_of_tos() & T_reg2) /* src */
+ b= pop_reg_reg (&bo_reg);
+ else
+ {
+ bo_reg= NULL;
+ b= pop_reg_c13(bc_str);
+ }
+ if (bo_reg)
+ "ld [$b+$bo_reg], $c";
+ else
+ "ld [$b+$bc_str], $c";
+ if (ao_reg)
+ "st $c, [$a+$ao_reg]";
+ else
+ "st $c, [$a+$ac_str]";
+ if (bo_reg)
+ {
+ push_reg(b);
+ inc_tos_reg(bo_reg);
+ }
+ else if (bc_str[0] == '-' ||
+ isdigit(bc_str[0]))
+ {
+ push_reg(b);
+ inc_tos(atoi(bc_str));
+ }
+ else
+ {
+ "add $b, $bc_str, $c";
+ push_reg(c);
+ free_reg(b);
+ c= alloc_reg();
+ }
+ inc_tos(4);
+ if (ao_reg)
+ {
+ push_reg(a);
+ inc_tos_reg(ao_reg);
+ }
+ else if (ac_str[0] == '-' ||
+ isdigit(ac_str[0]))
+ {
+ push_reg(a);
+ inc_tos(atoi(ac_str));
+ }
+ else
+ {
+ "add $a, $ac_str, $c";
+ push_reg(c);
+ free_reg(a);
+ c= alloc_reg();
+ }
+ inc_tos(4);
+ }
+ pop_nop(2);
+ free_reg(c);
+ }
+ else
+ {
+ a= pop_reg(); /* dest */
+ b= pop_reg(); /* src */
+ c= alloc_reg();
+ d= alloc_reg();
+ "set $n_str, $c";
+ "1:";
+ "deccc 4, $c";
+ "ld [$b+$c], $d";
+ "bnz 1b";
+ "st $d, [$a+$c]";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }
+ else
+ {
+
+ c= pop_reg(); /* size */
+ a= pop_reg(); /* dest */
+ b= pop_reg(); /* src */
+ d= alloc_reg();
+ "1:";
+ "deccc 4, $c";
+ "ld [$b+$c], $d";
+ "bnz 1b";
+ "st $d, [$a+$c]";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }.
+
+ default ==>
+ arg_error( "bls", $1).
+
+narg4(bls)
+
+C_csa
+ $1 == 4 ==>
+ Comment( csa , $1 );
+ {
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ pop_reg_as(reg_o1);
+ flush_cache();
+ free_output();
+ "set csa, $reg_tmp";
+ "jmp $reg_tmp";
+ "nop";
+ }.
+ default ==>
+ arg_error( "csa", $1).
+
+narg4(csa)
+
+C_csb
+ $1 == 4 ==>
+ Comment( csb , $1 );
+ {
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ pop_reg_as(reg_o1);
+ flush_cache();
+ free_output();
+ "set csb, $reg_tmp";
+ "jmp $reg_tmp";
+ "nop";
+ }.
+ default ==>
+ arg_error( "csb", $1).
+
+narg4(csb)
+
+C_dch ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ Comment0( dch );
+ a= pop_reg(); /* some LB */
+ b= alloc_reg();
+ c= alloc_reg();
+ "ta 3"; /* flush register windows */
+ "add $a, 7, $b";
+ "andn $b, 7, $c"; /* and it's %fp */
+ "ld [$c+4], $b"; /* the previous LB */
+ free_reg(a);
+ push_reg(b);
+ free_reg(c);
+ }.
+
+C_dup ==>
+ Comment( dup, $1);
+ push_const($1);
+ C_dus(EM_WSIZE).
+
+C_dus
+ $1 == 4 ==>
+ {
+ int n;
+ int i;
+ const_str_t n_str;
+ const_str_t i_str;
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ Comment( dus, $1);
+
+ if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
+ {
+ n= pop_const(n_str);
+ if (n == 4 || n == 8 || n<=32)
+ dup_tos(n/4);
+ else if (n<0 || n % 4)
+ arg_error ("dup", n);
+ else
+ {
+ flush_cache();
+ a= alloc_reg();
+ "sub $reg_sp, $n_str, $reg_sp";
+ for (i=0; i<n; i += 4)
+ {
+ sprintf(i_str, "%d", i);
+ "ld [$reg_sp+$i_str+$n_str], $a";
+ "st $a, [$reg_sp+$i_str]";
+ }
+ free_reg(a);
+ }
+ }
+ else
+ {
+ a= pop_reg();
+ flush_cache();
+ b= alloc_reg();
+ c= alloc_reg();
+ "mov $a, $b";
+ "1:";
+ "dec STACK_CLICK, $reg_sp";
+ "ld [$reg_sp+ $a], $c";
+ "deccc 4, $b";
+ "bne 1b";
+ "st $c, [$reg_sp+ $a]"; /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ }
+ }.
+ default ==>
+ arg_error( "dus", $1).
+
+narg4(dus)
+
+C_exg ==>
+ Comment( exg, $1 );
+ push_const($1);
+ C_exg_narg().
+
+C_exg_narg ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+ int n;
+ int i;
+ const_str_t i_str;
+ const_str_t in_str;
+
+ Comment0( exg_narg );
+ if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
+ {
+ n= pop_const(NULL);
+ if (n==4)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ push_reg(a);
+ push_reg(b);
+ }
+ else if (n==8)
+ {
+ a= pop_reg();
+ b= pop_reg();
+ c= pop_reg();
+ d= pop_reg();
+ push_reg(b);
+ push_reg(a);
+ push_reg(d);
+ push_reg(c);
+ }
+ else if (n>0 && !(n % 4))
+ {
+ a= alloc_reg();
+ b= alloc_reg();
+ flush_cache();
+ for (i=0; i<n; i += 4)
+ {
+ sprintf(i_str, "%d", i);
+ sprintf(in_str, "%d", i+n);
+ "ld [$reg_sp+$i_str], $a";
+ "ld [$reg_sp+$in_str], $b";
+ "st $b, [$reg_sp+$i_str]";
+ "st $a, [$reg_sp+$in_str]";
+ }
+ free_reg(a);
+ free_reg(b);
+ }
+ else
+ arg_error ("exg", n);
+ }
+ else
+ {
+ a= pop_reg();
+ flush_cache();
+ b= alloc_reg();
+ c= alloc_reg();
+ d= alloc_reg();
+ "add $reg_sp, $a, $b";
+ "1:";
+ "dec 4, $b";
+ "cmp $reg_sp, $b";
+ "ld [$b], $c";
+ "ld [$b+$a], $d";
+ "st $d, [$b]";
+ "bne 1b";
+ "st $c, [$b+$a]"; /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }
+ }.
+
+C_fil.. ==>
+ Comment2( fil , $1 , $2);
+#ifdef FAST_LIN_LNI_FIL
+ {
+ char *lbl = $1;
+ int n = $2;
+
+ "set $lbl+$n, $reg_fil"
+ }.
+#else
+ push_ext($1);
+ inc_tos($2);
+ push_ext("filn");
+ push_const(4);
+ C_sts(EM_WSIZE).
+#endif
+
+
+C_gto.. ==>
+ {
+ char *ext;
+ reg_t a;
+ reg_t b;
+ reg_t c;
+ reg_t d;
+
+ Comment2( gto , $1 , $2 );
+
+ flush_cache();
+ a= reg_g1;
+ b= reg_g2;
+ c= reg_g3;
+ d= reg_g5;
+ forced_alloc_reg(a);
+ forced_alloc_reg(b);
+ forced_alloc_reg(c);
+ forced_alloc_reg(d);
+ ext= $1;
+ push_ext(ext);
+ inc_tos($2);
+ pop_reg_as(a);
+ "ld [$a+8], $b";
+ "mov $reg_o0, $c";
+ "mov $reg_o1, $d";
+ "1:";
+ "cmp $b, $reg_lb";
+ "bne,a 1b";
+ "restore";
+ "ld [$a+4], $reg_sp";
+ "ld [$a], $b";
+ "mov $c, $reg_o0";
+ "jmp $b";
+ "mov $d, $reg_o1"; /* delay slot */
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_reg(d);
+ }.
+
+C_lim ==>
+ Comment0( lim );
+ push_ext("trpim");
+ C_loi(4).
+
+C_lin ==>
+ Comment( lin , $1 );
+#ifdef FAST_LIN_LNI_FIL
+ {
+ const_str_t n_str;
+ sprintf(n_str, "%d", $1);
+ "set $n_str, $reg_fil";
+ }.
+#else
+ push_const($1);
+ push_ext("lino");
+ push_const(4);
+ C_sts(EM_WSIZE).
+#endif
+
+C_lni ==>
+#ifdef FAST_LIN_LNI_FIL
+ Comment0( lni );
+ "inc $reg_fil".
+#else
+ {
+ reg_t a;
+ reg_t b;
+
+ Comment0( lni );
+ a = alloc_reg();
+ b = alloc_reg();
+ "sethi %hi(lino), $a";
+ "ld [$a+%lo(lino)], $b";
+ "inc $b";
+ "st $b, [$a+%lo(lino)]"
+ free_reg(a);
+ free_reg(b);
+ }.
+#endif
+
+
+C_lor
+ $1 == 0 ==>
+ Comment( lor , $1 );
+ soft_alloc_reg(reg_lb);
+ push_reg(reg_lb).
+ $1 == 1 ==>
+ {
+ reg_t a;
+
+ Comment( lor , $1 );
+ a= alloc_reg();
+ flush_cache();
+ "mov $reg_sp, $a";
+ push_reg(a);
+ }.
+ $1 == 2 ==>
+ Comment( lor , $1 );
+ {
+ reg_t a;
+ reg_t b;
+
+ a= alloc_reg();
+ b= alloc_reg();
+ "set reghp, $a";
+ "ld [$a], $b";
+ push_reg(b);
+ free_reg(a);
+ }.
+
+ default ==>
+ arg_error( "lor", $1).
+
+
+C_lpb ==>
+ Comment0( lpb );
+ C_adp( (arith)EM_BSIZE).
+
+
+C_mon ==>
+ Comment0( mon );
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ "call mon";
+ "nop";
+ free_output().
+
+C_nop ==>
+ Comment0( nop );
+ flush_cache();
+ .
+
+
+C_rck
+ $1 == 4 ==>
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ Comment( rck , $1 );
+ force_alloc_output();
+ a= pop_reg();
+ b= pop_reg();
+ soft_alloc_reg(b);
+ push_reg(b);
+ c= alloc_reg();
+ "ld [$a], $c";
+ "cmp $b, $c";
+ "bl 1f";
+ "ld [$a+4], $c";
+ "cmp $b, $c";
+ "ble 2f";
+ "nop";
+ "1:";
+ "set ERANGE, $reg_o0";
+ "call trp";
+ "nop";
+ "2:";
+ free_reg(a);
+ free_reg(b);
+ free_reg(c);
+ free_output();
+ }.
+ default ==>
+ arg_error( "rck", $1).
+
+narg4(rck)
+
+C_rtt ==>
+ Comment0( rtt );
+ C_ret( (arith)0).
+
+
+C_sig ==>
+ Comment0( sig );
+ {
+ reg_t a;
+ reg_t b;
+ reg_t c;
+
+ a= pop_reg();
+ b= alloc_reg();
+ c= alloc_reg();
+ "set trppc, $b";
+ "ld [$b], $c";
+ "st $a, [$b]";
+ free_reg(a);
+ free_reg(b);
+ push_reg(c);
+ }.
+
+
+C_sim ==>
+ Comment0( sim );
+ {
+ reg_t a;
+ reg_t b;
+
+ a= pop_reg();
+ b= alloc_reg();
+ "set trpim, $b";
+ "st $a, [$b]";
+ free_reg(a);
+ free_reg(b);
+ }.
+
+
+C_str
+ $1 == 0 ==>
+ Comment( str , $1 );
+ "ld [$reg_sp], $reg_lb";
+ "inc STACK_CLICK, $reg_sp"
+ .
+ $1 == 1 ==>
+ {
+ Comment( str , $1 );
+ pop_reg_as(reg_sp);
+ }.
+ $1 == 2 ==>
+ {
+ Comment( str , $1 );
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ "call strhp";
+ "nop";
+ free_output();
+ }.
+ default ==>
+ arg_error( "str", $1).
+
+
+C_trp ==>
+ Comment0( trp );
+ force_alloc_output();
+ pop_reg_as(reg_o0);
+ flush_cache();
+ "call trp";
+ "nop";
+ free_output().
+
+/*****************************************************************************/
+
+..icon
+ $2 == 1 ==>
+ Comment( ..icon , $1 );
+ gen1( (ONE_BYTE) atoi( $1)).
+ $2 == 2 ==>
+ Comment( ..icon , $1 );
+ gen2( (TWO_BYTES) atoi( $1)).
+ $2 == 4 ==>
+ Comment( ..icon , $1 );
+ gen4( (FOUR_BYTES) atol( $1)).
+ default ==>
+ arg_error( "icon", $2).
+
+..ucon
+ $2 == 1 ==>
+ Comment( ..ucon , $1 );
+ gen1( (ONE_BYTE) atoi( $1)).
+ $2 == 2 ==>
+ Comment( ..ucon , $1 );
+ gen2( (TWO_BYTES) atoi( $1)).
+ $2 == 4 ==>
+ Comment( ..ucon , $1 );
+ gen4( (FOUR_BYTES) atol( $1)).
+ default ==>
+ arg_error( "icon", $2).
+
+..fcon ==>
+ Comment( ..fcon , $1 );
+ con_float($1, $2).
+
+/*****************************************************************************/
+
+C_prolog ==>
+ Comment0( prolog );
+ init_cache();
+ "sub $reg_sp, (EM_BSIZE-4), %g1";
+ "and %g1, -8, %sp";
+ "mov $reg_sp, %g1";
+ "save %sp, $reg_gap, %sp";
+ "st %g0, [%sp+BP_OFFSET]";
+ "sub %g1, EM_BSIZE, $reg_lb";
+ init_reg_man();
+ forced_alloc_reg(reg_sp);
+ forced_alloc_reg(reg_lb);
+ forced_alloc_reg(reg_gap);
+#ifdef FAST_LIN_LNI_FIL
+ reg_lin = alloc_reg();
+ reg_fil = alloc_reg();
+#endif
+ .
+C_jump ==>
+ {
+ char *l;
+
+ Comment( jump , $1 );
+ l= $1;
+ "b $l";
+ "nop"; /* delay slot */
+ }.
+
+C_locals ==>
+ {
+ Comment( locals , $1 );
+
+ soft_alloc_reg(reg_sp);
+ push_reg(reg_lb);
+ inc_tos(-($1));
+ pop_reg_as(reg_sp);
+ }.
--- /dev/null
+SED = sed
+M4 = m4
+CPP = /lib/cpp
+
+all: EM_table cache.c
+
+distr: all
+
+EM_table: EM_table.x cegpp
+ $(CPP) < EM_table.x -P | $(M4) | $(SED) -f cegpp > $@
+
+cache.c: cache.c.x cegpp
+ $(SED) -f cegpp cache.c.x > $@
--- /dev/null
+Makefile
+back.h
+con_str.c
+const.h
+do_open.c
+gen_str.c
+header.h
+rom_str.c
+symboldef.c
--- /dev/null
+# $Header$
+
+# requires a definition for TARGET_HOME, SRC_DIR, CFLAGS, CC
+
+CEG=$(TARGET_HOME)/lib.bin/ceg
+SOURCE=$(CEG)/ce_back/as_back
+
+IDIRS=-I.\
+ -I$(SRC_DIR)\
+ -I..\
+ -I$(TARGET_HOME)/h\
+ -I$(TARGET_HOME)/modules/h
+
+all : bottom.o con1.o con2.o con4.o end_back.o gen1.o gen2.o\
+ gen4.o init_back.o reloc1.o reloc2.o reloc4.o bss.o\
+ rom1.o rom2.o rom4.o set_global.o set_local.o switchseg.o symboldef.o \
+ do_open.o do_close.o text1.o text2.o text4.o con_str.o gen_str.o rom_str.o
+
+bottom.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/bottom.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/bottom.c
+
+bss.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/bss.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/bss.c
+
+text1.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/text1.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/text1.c
+
+text2.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/text2.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/text2.c
+
+text4.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/text4.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/text4.c
+
+con1.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/con1.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con1.c
+
+con2.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/con2.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con2.c
+
+con4.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/con4.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con4.c
+
+do_open.o : back.h header.h $(SRC_DIR)/mach.h do_open.c
+ $(CC) $(CFLAGS) -c $(IDIRS) do_open.c
+
+do_close.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/do_close.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/do_close.c
+
+gen1.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/gen1.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen1.c
+
+gen2.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/gen2.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen2.c
+
+gen4.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/gen4.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen4.c
+
+init_back.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/init_back.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/init_back.c
+
+end_back.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/end_back.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/end_back.c
+
+reloc1.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/reloc1.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc1.c
+
+reloc2.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/reloc2.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc2.c
+
+reloc4.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/reloc4.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc4.c
+
+rom1.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/rom1.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom1.c
+
+rom2.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/rom2.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom2.c
+
+rom4.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/rom4.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom4.c
+
+set_global.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/set_global.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/set_global.c
+
+set_local.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/set_local.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/set_local.c
+
+switchseg.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/switchseg.c
+ $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/switchseg.c
+
+symboldef.o : header.h back.h $(SRC_DIR)/mach.h symboldef.c
+ $(CC) $(CFLAGS) -c $(IDIRS) symboldef.c
+
+con_str.o : header.h back.h $(SRC_DIR)/mach.h con_str.c
+ $(CC) $(CFLAGS) -c $(IDIRS) con_str.c
+
+gen_str.o : header.h back.h $(SRC_DIR)/mach.h gen_str.c
+ $(CC) $(CFLAGS) -c $(IDIRS) gen_str.c
+
+rom_str.o : header.h back.h $(SRC_DIR)/mach.h rom_str.c
+ $(CC) $(CFLAGS) -c $(IDIRS) rom_str.c
--- /dev/null
+#include <em.h>
+#include <system.h>
+
+#define codefile B_codefile
+#define cur_seg B_cur_seg
+#define saved B_saved
+#define labeltje B_labeltje
+#define name B_name
+#define output_back B_output_back
+
+/* Macros to change interface names */
+
+#define common B_common
+#define con1 B_con1
+#define con2 B_con2
+#define con4 B_con4
+#define con_str B_con_str
+#define rom1 B_rom1
+#define rom2 B_rom2
+#define rom4 B_rom4
+#define rom_str B_rom_str
+#define text1 B_txt1
+#define text2 B_txt2
+#define text4 B_txt4
+#define close_back B_close_back
+#define open_back B_open_back
+#define end_back B_end_back
+#define init_back B_init_back
+#define extnd_pro B_ex_pro
+#define extnd_start B_ex_start
+#define extnd_name B_ex_name
+#define extnd_dnam B_ex_dnam
+#define extnd_dlb B_ex_dlb
+#define extnd_ilb B_ex_ilb
+#define extnd_hol B_ex_hol
+#define extnd_part B_ex_part
+#define extnd_cont B_ex_cont
+#define extnd_main B_ex_main
+#define gen1 B_gen1
+#define gen2 B_gen2
+#define gen4 B_gen4
+#define gen_str B_gen_str
+#define save_label B_save_label
+#define dump_label B_dump_label
+#define align_word B_align_word
+#define reloc1 B_rlc1
+#define reloc2 B_rlc2
+#define reloc4 B_rlc4
+#define set_global_visible B_stglobvis
+#define set_local_visible B_stlocvis
+#define symbol_definition B_symdef
+#define switchseg B_switchseg
+
+extern File *codefile;
+
+extern char *extnd_name(), *extnd_dnam(), *extnd_dlb(), *extnd_ilb(),
+ *extnd_hol(), *extnd_ext(), *extnd_pro(), *extnd_start(),
+ *extnd_part(), *extnd_cont(), *extnd_main();
+
+#define swtxt() switchseg( SEGTXT)
+#define bss(n) fprint(codefile, BSS_FMT, (long)(n))
+
+#define SEGTXT 0
+#define SEGROM 1
+#define SEGCON 2
+#define SEGBSS 3
+#define SEGHOL -1 /* Does not exist */
+
+#define ABSOLUTE 1
--- /dev/null
+#include "header.h"
+
+con_str(s,n)
+char *s;
+int n;
+{
+ gen_str( s,n);
+}
--- /dev/null
+#define TRUE 1
+#define FALSE 0
--- /dev/null
+#include "header.h"
+
+open_back( filename)
+char *filename;
+{
+ if ( filename == (char *) 0)
+ codefile= STDOUT;
+ else
+ return( sys_open( filename, OP_WRITE, &codefile));
+ return 1;
+}
--- /dev/null
+#include "header.h"
+
+gen_str( s,n)
+char *s;
+int n;
+{
+ unsigned char c;
+ switch ( cur_seg) {
+ case SEGTXT :
+ case SEGCON :
+ case SEGROM :
+ fprint( codefile, "%s\"", STR_FMT);
+ while (n--)
+ {
+ c= *s++;
+ if (isprint(c) && c != '"')
+ fprint(codefile, "%c", c);
+ else
+ fprint(codefile, "\\%03o", c);
+ }
+ fprint( codefile, "\"\n");
+ break;
+ case SEGBSS : bss( (arith) 1);
+ break;
+ default : fprint( STDERR, "gen1 unkown seg %d\n", cur_seg);
+ }
+}
--- /dev/null
+#include "mach.h"
+#include "back.h"
+
+extern int cur_seg;
--- /dev/null
+#include "header.h"
+
+rom_str( s,n)
+char *s;
+int n;
+{
+ gen_str( s,n);
+}
--- /dev/null
+#include "header.h"
+
+symbol_definition( s)
+char *s;
+{
+ if (cur_seg == SEGTXT)
+ flush_cache(); /* EXTRA */
+ fprint( codefile, SYMBOL_DEF_FMT, s);
+}
--- /dev/null
+/* cache.c */
+
+#include <stdio.h>
+#include </usr/include/assert.h>
+#include <malloc.h>
+#include <string.h>
+#include <strings.h>
+#include "mach.h"
+
+#define free_reg_num(i) if (1) { assert(reg[i].inuse > 0); reg[i].inuse--; if (debug) fprintf(stderr,"free_reg(%s)\n", regnam[i]); } else
+
+#define POP1 cache_need(1);
+#define POP2 { --tos; assert(c_count); --c_count; }
+
+int indent_count = 0;
+
+#define enter(x) indent_count++;
+#define indent() { int i = indent_count; while (i--) putc('\t', stderr); }
+#define leave(x) indent_count--;
+
+/* procedures:
+ const13(int) boolean proc
+ init_cache() mandatory
+ free_reg(reg_t)
+ forced_alloc_reg(reg_t)
+ soft_alloc_reg(reg_t)
+ change_reg(reg_t) used when reg on stack has changed
+ type_of_tos() bit-field representation of ext/reg/cst
+ inc_tos(int) tos->cst += n
+ push_const(int)
+ push_reg(reg_t)
+ push_ext(char *)
+ flush_cache() after branches and labels
+ cache_read(int) read-ahead. optimization only
+ dump_cache(FILE *) debug info: show current stack
+ pop_nop() remove element from cache
+
+ reg_t alloc_reg()
+ reg_t pop_reg()
+ reg_t pop_reg_c13(char*)
+
+ arith pop_const(char *)
+ arith top_const()
+
+ alloc_float, alloc_double, free_double,
+ pop_float, pop_double, push_float, push_double
+
+*/
+
+typedef struct regdat_t {
+ int inuse; /* free == 0, otherwise #owners */
+} regdat_t;
+/*
+typedef struct cache_elt {
+ reg_t reg, reg2;
+ char *ext;
+ arith cst;
+} cache_elt;
+*/
+char regnam[][8] = {
+/*x*/ "%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+/*x*/ "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%i6", "%i7",
+/*x*/ "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
+/*x*/ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o6", "%o7",
+/*x*/ "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+/*x*/ "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
+/*x*/ "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
+/*x*/ "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"
+};
+
+reg_t reg_g0, reg_g1, reg_g2, reg_g3, reg_g4, reg_g5, reg_g6, reg_g7;
+reg_t reg_i0, reg_i1, reg_i2, reg_i3, reg_i4, reg_i5, reg_i6, reg_i7;
+reg_t reg_l0, reg_l1, reg_l2, reg_l3, reg_l4, reg_l5, reg_l6, reg_l7;
+reg_t reg_o0, reg_o1, reg_o2, reg_o3, reg_o4, reg_o5, reg_o6, reg_o7;
+reg_t reg_f0;
+reg_t reg_sp, reg_lb, reg_gap;
+reg_t reg_tmp, reg_lin, reg_fil;
+
+struct regdat_t reg[NR_REGS];
+
+#define POP_SIZE 1 /* maybe >1 (read-ahead cache) or explicit?! */
+#define CACHE_SIZE 32 /* ? */
+#define LO_GLOB 0
+#define HI_GLOB 7
+#define LO_IN 8
+#define HI_IN 15
+#define LO_LOC 16
+#define HI_LOC 23
+#define LO_OUT 24
+#define HI_OUT 31
+#define LO_FLOAT 32
+#define HI_FLOAT 63
+const13(x)
+{
+ return (x < 4096 && x >= -4096);
+}
+
+struct cache_elt cache[CACHE_SIZE], *tos = 0;
+int c_count = 0;
+const_str_t s;
+
+static void panic(s)
+char *s;
+{
+ printf("PANIC: %s\n", s);
+ exit(1);
+}
+
+void init_cache()
+{
+ int i;
+
+ for (i = 0; i < NR_REGS; i++)
+ reg[i].inuse = 0;
+
+ reg_g0 = regnam[000];
+ reg_g1 = regnam[001];
+ reg_g2 = regnam[002];
+ reg_g3 = regnam[003];
+ reg_g4 = regnam[004];
+ reg_g5 = regnam[005];
+ reg_g6 = regnam[006];
+ reg_g7 = regnam[007];
+
+ reg_i0 = regnam[010];
+ reg_i1 = regnam[011];
+ reg_i2 = regnam[012];
+ reg_i3 = regnam[013];
+ reg_i4 = regnam[014];
+ reg_i5 = regnam[015];
+ reg_i6 = regnam[016];
+ reg_i7 = regnam[017];
+
+ reg_l0 = regnam[020];
+ reg_l1 = regnam[021];
+ reg_l2 = regnam[022];
+ reg_l3 = regnam[023];
+ reg_l4 = regnam[024];
+ reg_l5 = regnam[025];
+ reg_l6 = regnam[026];
+ reg_l7 = regnam[027];
+
+ reg_o0 = regnam[030];
+ reg_o1 = regnam[031];
+ reg_o2 = regnam[032];
+ reg_o3 = regnam[033];
+ reg_o4 = regnam[034];
+ reg_o5 = regnam[035];
+ reg_o6 = regnam[036];
+ reg_o7 = regnam[037];
+
+ reg_f0 = regnam[040];
+
+ reg_sp = reg_l0;
+ reg_lb = reg_l1;
+ reg_gap = reg_g4;
+ reg_tmp = reg_o7;
+ forced_alloc_reg(reg_g0); /* can not be used as a reg */
+ forced_alloc_reg(reg_o6);
+ forced_alloc_reg(reg_o7);
+ forced_alloc_reg(reg_i6);
+ forced_alloc_reg(reg_i7);
+}
+
+static void flush_part_cache(n,r,f,d)
+int n,r,f,d;
+{
+/* free at least n entries, r integer registers, f float regs and d double regs
+ */
+ int i, ready;
+ int rn, j;
+ const_str_t i_str, e_str, n_str;
+ char *ext, R1, R2;
+ reg_t rh, rt;
+
+enter("flush_part_cache");
+ for (i = 0; i < c_count; i++)
+ {
+ if (i >= n && !r && !f && !d)
+ break;
+ if (cache[i].reg != reg_g0)
+ {
+ rn= REG_NUM(cache[i].reg);
+ free_reg_num(rn);
+ if (!reg[rn].inuse)
+ if (rn<LO_FLOAT)
+ {
+ if (r)
+ r--;
+ }
+ else
+ {
+ if (d && (((rn & 1) &&
+ !reg[rn-1].inuse) ||
+ (!(rn & 1) && !reg[rn+1].inuse)))
+ d--;
+ if (f)
+ f--;
+ }
+ }
+ if (cache[i].reg2 != reg_g0)
+ {
+ rn= REG_NUM(cache[i].reg2);
+ free_reg_num(rn);
+ if (!reg[rn].inuse)
+ if (rn<LO_FLOAT)
+ {
+ if (r)
+ r--;
+ }
+ else
+ {
+ if (d && (((rn & 1) &&
+ !reg[rn-1].inuse) ||
+ (!(rn & 1) && !reg[rn+1].inuse)))
+ d--;
+ if (f)
+ f--;
+ }
+ }
+ }
+ if (r || f || d)
+ panic ("can't free enough registers");
+ j = i;
+ if (i)
+ {
+ sprintf (i_str, "%d", 4*i);
+ "dec $i_str, $reg_sp";
+ while (i--)
+ {
+ sprintf(i_str, "%d", 4*(j-1-i));
+ if (cache[i].ext)
+ {
+ ext= cache[i].ext;
+ sprintf (e_str, "%d", cache[i].cst);
+ "set $ext+$e_str, $reg_tmp";
+ "st $reg_tmp, [$reg_sp+$i_str]";
+ free(ext);
+ }
+ else
+ {
+ if (cache[i].reg2 != reg_g0)
+ {
+ rt = cache[i].reg;
+ rh = cache[i].reg2;
+ "add $rt, $rh, $reg_tmp";
+ cache[i].reg = reg_tmp;
+ cache[i].reg2 = reg_g0;
+ }
+ if (!const13(cache[i].cst))
+ {
+ sprintf(n_str, "%d",
+ cache[i].cst);
+ "sethi %hi($n_str), $reg_tmp";
+ if (cache[i].reg != reg_g0)
+ {
+ rt = cache[i].reg;
+ "add $reg_tmp, $rt, $reg_tmp";
+ }
+ rh= reg_tmp;
+ cache[i].cst &= 0x3ff;
+ }
+ else {
+ rh= cache[i].reg;
+ }
+ if (cache[i].cst)
+ {
+ sprintf(n_str, "%d", cache[i].cst);
+ "add $rh, $n_str, $reg_tmp";
+ rh= reg_tmp;
+ }
+ "st $rh, [$reg_sp+$i_str]";
+ }
+ }
+ for (i= j; i < c_count; i++)
+ cache[i-j]= cache[i];
+ c_count -= j;
+ tos= &cache[c_count-1];
+ }
+leave("flush_part_cache");
+}
+
+reg_t alloc_reg()
+{
+ int i;
+ reg_t res = NULL;
+
+enter("alloc_reg");
+ for (i = LO_GLOB+1 /* SPEED-HACK */; i <= HI_GLOB; i++) {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+ if (!res)
+ for (i = LO_IN; i <= HI_IN; i++) {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+ if (!res)
+ for (i = LO_LOC; i <= HI_LOC; i++) {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+ if (!res)
+ for (i = LO_OUT; i <= HI_OUT; i++) {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+ if (!res) {
+ flush_part_cache(c_count/2,1,0,0);
+ res = alloc_reg();
+ }
+if (debug) { indent(); fprintf(stderr,"alloc_reg() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_reg");
+ return res;
+}
+
+reg_t alloc_float()
+{
+ int i;
+ reg_t res = NULL;
+
+enter("alloc_float");
+ for (i = LO_FLOAT+15; i >= LO_FLOAT; i--) {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+ if (!res) {
+ flush_part_cache(c_count/2,0,1,0);
+ res = alloc_float();
+ }
+if (debug) { indent(); fprintf(stderr,"alloc_float() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_float");
+ return res;
+}
+
+reg_t alloc_double(sub_reg)
+reg_t *sub_reg;
+{
+ int i;
+ reg_t res = NULL;
+
+enter("alloc_double");
+ for (i = LO_FLOAT+14; i >= LO_FLOAT; i -= 2) {
+ if (reg[i].inuse || reg[i+1].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ reg[i+1].inuse = 1; /* allocate */
+if (debug) { indent(); fprintf(stderr,"alloc_double() = %s\n", regnam[i]); }
+ if (sub_reg)
+ *sub_reg= regnam[i+1];
+ res = regnam[i];
+ break;
+ }
+ if (!res) {
+ flush_part_cache(c_count/2,0,0,1);
+ res = alloc_double(sub_reg);
+ }
+if (debug) { indent(); fprintf(stderr,"alloc_double() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_double");
+ return res;
+}
+
+reg_t alloc_reg_var() /* ins and locals only */
+{
+ int i;
+ reg_t res = NULL;
+
+enter("alloc_reg_var");
+ for (i = LO_LOC +2 /* SPEED-HACK */; i <= HI_LOC; i++) {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+ if (!res)
+ for (i = LO_IN; i <= HI_IN; i++) {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+if (debug) { indent(); fprintf(stderr,"alloc_reg_var() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_reg_var");
+ return res;
+}
+
+reg_t alloc_float_var()
+{
+ int i;
+ reg_t res = NULL;
+
+enter("alloc_float_var");
+ for (i= LO_FLOAT+16; i<= HI_FLOAT; i++)
+ {
+ if (reg[i].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ res = regnam[i];
+ break;
+ }
+if (debug) { indent(); fprintf(stderr,"alloc_reg_var() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_float_var");
+ return res;
+}
+
+reg_t alloc_double_var(sub_reg)
+reg_t *sub_reg;
+{
+ int i;
+ reg_t res = NULL;
+
+enter("alloc_double_var");
+ for (i = LO_FLOAT+16; i < HI_FLOAT; i += 2) {
+ if (reg[i].inuse || reg[i+1].inuse)
+ continue;
+ reg[i].inuse = 1; /* allocate */
+ reg[i+1].inuse = 1; /* allocate */
+if (debug) { indent(); fprintf(stderr,"alloc_double_var() = %s\n", regnam[i]); }
+ if (sub_reg)
+ *sub_reg= regnam[i+1];
+ res = regnam[i];
+ break;
+ }
+if (debug) { indent(); fprintf(stderr,"alloc_double_var() = %s\n", res? regnam[i] : "NULL"); }
+leave("alloc_double_var");
+ return res;
+}
+
+void free_reg(i)
+reg_t i;
+{
+ int r;
+
+enter("free_reg");
+ if (i != 0 && i != reg_g0) {
+ r = REG_NUM(i);
+ assert(0 <= r && r <= NR_REGS);
+ assert(reg[r].inuse > 0); /* "freeing unused register" */
+ reg[r].inuse--;
+ }
+if (debug) { indent(); fprintf(stderr,"free_reg(%s)\n", i); }
+leave("free_reg");
+}
+
+void free_double_reg(i)
+reg_t i;
+{
+ int rn;
+
+enter("free_double_reg");
+ rn= REG_NUM(i);
+ assert (!(rn & 1));
+ free_reg(i);
+ free_reg(regnam[rn+1]);
+leave("free_double_reg");
+}
+
+
+void force_alloc_output() /* TMP HACK */
+{
+ int i;
+
+enter("force_alloc_output");
+if (debug) { indent(); fprintf(stderr,"force_alloc_output\n"); }
+ for (i = REG_NUM(reg_o0); i <= REG_NUM(reg_o5); i++)
+ forced_alloc_reg(regnam[i]);
+leave("force_alloc_output");
+}
+
+void free_output()
+{
+ int i;
+
+enter("free_output");
+leave("free_output");
+if (debug) { indent(); fprintf(stderr,"free_output\n"); }
+ for (i = REG_NUM(reg_o0); i <= REG_NUM(reg_o5); i++) {
+ assert(reg[i].inuse > 0);
+ reg[i].inuse--;
+ }
+}
+
+void soft_alloc_reg(i)
+reg_t i;
+{
+enter("soft_alloc_reg");
+if (debug) { indent(); fprintf(stderr,"soft_alloc_reg(%s)\n", i); }
+ /* assert(reg[REG_NUM(i)].inuse); */
+ reg[REG_NUM(i)].inuse++;
+leave("soft_alloc_reg");
+}
+
+void forced_alloc_reg(i)
+reg_t i;
+{
+ int r;
+
+enter("forced_alloc_reg");
+if (debug) { indent(); fprintf(stderr,"forced_alloc_reg(%s)\n", i); }
+
+ r = REG_NUM(i);
+
+ if (reg[r].inuse) {
+ reg_t S1;
+ char *V2;
+
+ S1 = alloc_reg();
+if (debug) { indent(); fprintf(stderr,"---> inuse: moving to %s\n", S1); }
+ "mov $i, $S1";
+ subst_reg(i, S1);
+ free_reg(S1);
+ if (reg[r].inuse)
+ panic("forced_alloc_reg: external owners left!");
+ }
+ reg[r].inuse = 1;
+leave("forced_alloc_reg");
+}
+
+void change_reg(r) /* to be called when register r changes */
+reg_t r;
+{
+ int i;
+
+enter("change_reg");
+if (debug) { indent(); fprintf(stderr, "change_reg(%s)\n", r); }
+ if (r != reg_g0)
+ for (i = 0; i < c_count; i++)
+ if (cache[i].reg == r || cache[i].reg2 == r) {
+ reg_t S1;
+
+ if (r >= reg_f0) {
+ S1 = alloc_float();
+ "fmovs $r, $S1";
+ } else {
+ S1 = alloc_reg();
+ "mov $r, $S1";
+ }
+ subst_reg(r, S1);
+ free_reg(S1);
+ break;
+ }
+leave("change_reg");
+}
+
+static void subst_reg(old, new)
+reg_t old, new;
+{
+ int i;
+
+enter("subst_reg");
+if (debug) { indent(); fprintf(stderr,"subst_reg(%s, %s)\n", old, new); }
+ for (i = 0; i < c_count; i++) {
+ if (cache[i].reg == old) {
+ cache[i].reg = new;
+ free_reg(old);
+ soft_alloc_reg(new);
+ }
+ if (cache[i].reg2 == old) {
+ cache[i].reg2 = new;
+ free_reg(old);
+ soft_alloc_reg(new);
+ }
+ }
+leave("subst_reg");
+}
+
+int type_of_tos()
+{
+ int r = 0;
+
+ cache_need(1);
+
+ if (tos->ext)
+ r |= T_ext;
+ if (tos->reg != reg_g0)
+ if (tos->reg >= reg_f0)
+ r |= T_float;
+ else
+ r |= T_reg;
+ if (tos->reg2 != reg_g0)
+ if (tos->reg2 >= reg_f0)
+ r |= T_float2;
+ else
+ r |= T_reg2;
+ if (tos->cst)
+ r |= T_cst;
+ return r;
+}
+
+arith top_const()
+{
+enter("top_const");
+ assert(type_of_tos() == T_cst);
+if (debug) { indent(); fprintf(stderr,"top_const()=%d\n", tos->cst); }
+leave("top_const");
+ return tos->cst;
+}
+
+reg_t pop_reg_reg(r)
+reg_t *r;
+{
+ reg_t s;
+
+enter("pop_reg_reg");
+ POP1;
+ if (!(type_of_tos() & T_reg2))
+ push_reg(pop_reg());
+ assert(r);
+ *r = tos->reg2;
+ s = tos->reg;
+ POP2;
+if (debug) { indent(); fprintf(stderr,"pop_reg_reg()=%s\n", s); fprint(codefile,"\t\t! "); dump_cache(codefile); }
+leave("pop_reg_reg");
+ return s;
+}
+
+reg_t pop_reg_c13(n) /* returns reg_t + optional n (as string) */
+char *n;
+{
+ reg_t S1, S2, S3;
+ register char *V1;
+ const_str_t V2;
+enter("pop_reg_c13");
+if (debug) { indent(); fprintf(stderr,"pop_reg_c13()=...\n"); }
+ *n = '0';
+ *(n+1) = 0;
+ cache_need(1);
+
+ if (tos->reg >= reg_f0) { /* convert float to int */
+ S1= pop_float();
+ S2= alloc_reg();
+ "st $S1, [%fp+64]";
+ "ld [%fp+64], $S2";
+ free_reg(S1);
+ S1 = S2;
+ }
+ else if (tos->reg2 != reg_g0) { /* add integers */
+ S1 = pop_reg();
+ }
+ else if (tos->ext) {
+ assert(tos->reg == reg_g0);
+ S1 = alloc_reg();
+ V1 = tos->ext;
+ sprintf(V2, "%d", tos->cst);
+ "sethi %hi($V1+$V2), $S1";
+ sprintf(n, "%%lo(%s+%d)", tos->ext, tos->cst);
+ free(V1);
+ POP2;
+ } else {
+ S1 = tos->reg;
+ if (!(const13(tos->cst))) {
+ S3 = alloc_reg();
+ sprintf(V2, "%d", tos->cst);
+ "sethi %hi($V2), $S3";
+ if (tos->reg != reg_g0) {
+ S2 = alloc_reg();
+ "add $S3, $S1, $S2";
+ free_reg(S1);
+ free_reg(S3);
+ S1 = S2;
+ }
+ tos->cst &= 0x3FF;
+ }
+ sprintf(n, "%d", tos->cst);
+ POP2;
+ }
+if (debug) { indent(); fprint(codefile, "\t\t! %s+%s cache:", S1, n); dump_cache(codefile);}
+leave("pop_reg_c13");
+ return S1;
+}
+
+reg_t pop_float()
+{
+ reg_t S1, R1, R2;
+ char *V1, *V2;
+
+enter("pop_float");
+ cache_need(1);
+ S1 = tos->reg;
+ if (!(type_of_tos() & T_float)) {
+ S1 = pop_reg();
+ R2 = alloc_float();
+ "st $S1, [%fp+64]";
+ "ld [%fp+64], $R2";
+ free_reg(S1);
+ S1 = R2;
+ }
+ else if (tos->reg2 >= reg_f0) {
+ R1 = tos->reg2;
+ R2 = alloc_float();
+ "fadds $S1, $R1, $R2";
+ free_reg(S1);
+ free_reg(R1);
+ S1 = R2;
+ POP2;
+ } else
+ POP2;
+if (debug) { indent(); fprint(codefile, "\t\t! %s cache:", S1); dump_cache(codefile); }
+leave("pop_float");
+ return S1;
+}
+
+void inc_tos_reg(r)
+reg_t r;
+{
+enter("inc_tos_reg");
+if (debug) { indent(); fprintf(stderr, "inc_tos_reg(%s)\n", r); }
+ if (type_of_tos() != T_reg)
+ push_reg(pop_reg());
+ tos->reg2 = r;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("inc_tos_reg");
+}
+
+void inc_tos(n)
+arith n;
+{
+ reg_t S1;
+ char *V1, *V2;
+
+enter("inc_tos");
+if (debug) { indent(); fprintf(stderr,"inc_tos(%d)\n", n); }
+ cache_need(1);
+ if (tos->reg >= reg_f0)
+ {
+ S1= pop_reg();
+ push_reg(S1);
+ }
+ else if (tos->reg2 != reg_g0) {
+ S1= pop_reg();
+ push_reg(S1);
+ }
+ tos->cst += n;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("inc_tos");
+}
+
+#define INC_TOS if (c_count >= CACHE_SIZE) flush_part_cache(c_count/2,0,0,0); \
+ tos = &cache[c_count++];
+
+void push_const(n)
+arith n;
+{
+enter("push_const");
+ INC_TOS;
+ tos->reg = reg_g0;
+ tos->reg2 = reg_g0;
+ tos->ext = 0;
+ tos->cst = n;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_const");
+}
+
+void push_reg(i)
+reg_t i;
+{
+enter("push_reg");
+ assert(0 <= REG_NUM(i) && REG_NUM(i) < NR_REGS);
+ INC_TOS;
+ tos->reg = i;
+ tos->reg2 = reg_g0;
+ tos->ext = 0;
+ tos->cst = 0;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_reg");
+}
+
+
+void push_double_reg(i)
+reg_t i;
+{
+ int rn;
+
+enter("push_double_reg");
+ rn= REG_NUM(i);
+ assert (!(rn & 1));
+ INC_TOS;
+ tos->ext = 0;
+ tos->cst = 0;
+ tos->reg = regnam[rn+1];
+ tos->reg2 = reg_g0;
+ INC_TOS;
+ tos->ext = 0;
+ tos->cst = 0;
+ tos->reg = i;
+ tos->reg2 = reg_g0;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_double_reg");
+}
+
+void push_ext(s)
+char *s;
+{
+ char *p;
+
+enter("push_ext");
+ p = malloc(strlen(s)+1);
+ assert(p);
+
+ INC_TOS;
+ tos->reg = reg_g0;
+ tos->reg2 = reg_g0;
+ tos->ext = strcpy(p, s);
+ tos->cst = 0;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_ext");
+}
+
+arith pop_const(n)
+char *n;
+{
+ arith x;
+
+enter("pop_const");
+ POP1;
+ x = top_const();
+ POP2;
+ if (n)
+ sprintf(n, "%d", x);
+if (debug) { indent(); fprint(codefile, "\t\t! %d cache:", x); dump_cache(codefile); }
+leave("pop_const");
+ return x;
+}
+
+void pop_reg_as(r)
+reg_t r;
+{
+ reg_t S1, S2;
+ register char *V1, *V3;
+ const_str_t V2, c_str;
+ char *tos_ext;
+ reg_t tos_reg, tos_reg2;
+ int tos_cst;
+
+enter("pop_reg_as");
+if (debug) { indent(); fprintf(stderr,"pop_reg_as(%s)=...\n", r); }
+ if (c_count == 0) { /* special case */
+ "ld [%l0], $r";
+ "inc 4, %l0";
+ } else if (r >= reg_f0) {
+ if (tos->reg < reg_f0)
+ {
+ S1= pop_reg();
+ change_reg(r);
+ "st $S1, [%fp+64]";
+ "ld [%fp+64], $r";
+ free_reg(S1);
+ }
+ else
+ {
+ if (tos->reg2 == reg_g0) {
+ S1= pop_float();
+ change_reg(r);
+ if (S1 != r)
+ "fmovs $S1, $r";
+ free_reg(S1);
+ } else {
+ V1 = tos->reg;
+ V3 = tos->reg2;
+ POP2;
+ change_reg(r);
+ "fadds $V1, $V3, $r";
+ free_reg(V1);
+ free_reg(V3);
+ }
+ }
+ } else if (tos->reg >= reg_f0) {
+ S1= pop_float();
+ change_reg(r);
+ "st $S1, [%fp+64]";
+ "ld [%fp+64], $r";
+ free_reg(S1);
+ } else if (tos->ext) {
+ assert(tos->reg == reg_g0);
+ V1 = tos->ext;
+ sprintf(V2, "%d", tos->cst);
+ "set $V1+$V2, $r";
+ free(V1);
+ POP2;
+ } else {
+ POP1;
+ tos_reg= tos->reg;
+ tos_reg2= tos->reg2;
+ tos_cst= tos->cst;
+ POP2;
+ change_reg(r);
+ if (!const13(tos_cst))
+ {
+ assert (tos_reg2 == reg_g0);
+ if (tos_reg != reg_g0 || (tos_cst & 0x3ff))
+ tos_reg2= alloc_reg();
+ else
+ {
+ soft_alloc_reg(r);
+ tos_reg2= r;
+ }
+ sprintf(c_str, "%d", tos_cst);
+ "sethi %hi($c_str), $tos_reg2";
+ tos_cst &= 0x3ff;
+ if (tos_reg == reg_g0)
+ {
+ tos_reg= tos_reg2;
+ tos_reg2= reg_g0;
+ }
+ }
+ if (tos_reg2 != reg_g0)
+ {
+ assert (tos_reg != reg_g0);
+ if (tos_cst)
+ S1= alloc_reg();
+ else
+ {
+ soft_alloc_reg(r);
+ S1= r;
+ }
+ "add $tos_reg, $tos_reg2, $S1";
+ free_reg(tos_reg);
+ free_reg(tos_reg2);
+ tos_reg= S1;
+ tos_reg2= reg_g0;
+ }
+ if (tos_cst)
+ {
+ sprintf(c_str, "%d", tos_cst);
+ soft_alloc_reg(r);
+ "add $tos_reg, $c_str, $r";
+ free_reg(tos_reg);
+ tos_reg= r;
+ }
+ if (tos_reg != r)
+ "mov $tos_reg, $r";
+ free_reg(tos_reg);
+ }
+leave("pop_reg_as");
+}
+
+void pop_double_reg_as(rdl)
+reg_t rdl;
+{
+ reg_t rl, rh;
+ reg_t rdh;
+ reg_t t;
+ int rn;
+
+enter("pop_double_reg_as");
+ rn= REG_NUM(rdl);
+ assert (!(rn & 1));
+ rdh= regnam[rn+1];
+ if (rdl>= reg_f0)
+ {
+ if (c_count == 0) {
+ "ld [%l0], $rdl";
+ "ld [%l0+4], $rdh";
+ "inc 8, %l0";
+ } else {
+ if (type_of_tos() & T_float)
+ rl= pop_float();
+ else
+ rl= pop_reg();
+ if (type_of_tos() & T_float)
+ rh= pop_float();
+ else
+ rh= pop_reg();
+ change_reg(rdl);
+ change_reg(rdh);
+ if (rl < reg_f0 && rh < reg_f0)
+ {
+ "st $rl, [%fp+64]";
+ "st $rh, [%fp+68]";
+ "ldd [%fp+64], $rdl";
+ free_reg(rl);
+ free_reg(rh);
+ }
+ else if (rl < reg_f0)
+ {
+ if (rh != rdh)
+ "fmovs $rh, $rdh";
+ "st $rl, [%fp+64]";
+ "ld [%fp+64], $rdl";
+ free_reg(rl);
+ free_reg(rh);
+ }
+ else if (rh < reg_f0)
+ {
+ if (rl != rdl)
+ "fmovs $rl, $rdl";
+ "st $rh, [%fp+64]";
+ "ld [%fp+64], $rdh";
+ free_reg(rl);
+ free_reg(rh);
+ } else {
+ if (rdl == rl)
+ free_reg(rl);
+ if (rdh == rh)
+ free_reg(rh);
+ if (rdl == rh && rdh == rl)
+ {
+ t= alloc_float();
+ "fmovs $rl, $t";
+ free_reg(rl);
+ rl= t;
+ }
+ if (rdl != rl && rdl != rh)
+ {
+ "fmovs $rl, $rdl";
+ free_reg(rl);
+ rl= rdl;
+ }
+ if (rdh != rh && rdh != rl)
+ {
+ "fmovs $rh, $rdh";
+ free_reg(rh);
+ rh= rdh;
+ }
+ if (rdl != rl && rdl != rh)
+ {
+ "fmovs $rl, $rdl";
+ free_reg(rl);
+ rl= rdl;
+ }
+ assert (rdl == rl && rdh == rh);
+ }
+ }
+ }
+ else
+ {
+ pop_reg_as (rdl);
+ pop_reg_as (rdh);
+ }
+leave("pop_double_reg_as");
+}
+
+
+
+reg_t pop_reg()
+{
+ reg_t S1;
+
+enter("pop_reg");
+ POP1;
+ if (type_of_tos() == T_reg) {
+ S1 = tos->reg;
+ POP2;
+ } else {
+ S1 = alloc_reg();
+ pop_reg_as(S1);
+ }
+if (debug) { indent(); fprint(codefile, "\t\t! %s cache:", S1); dump_cache(codefile); }
+leave("pop_reg");
+ return S1;
+}
+
+
+reg_t pop_double(sub_reg) /* pop_double_float actually */
+reg_t *sub_reg;
+{
+ reg_t R1, R2, R3, R4;
+ char *V1, *V2;
+
+enter("pop_double");
+ if (c_count == 0) {
+ R1 = alloc_double(&R2);
+ "ld [%l0], $R1";
+ "ld [%l0+4], $R2";
+ "inc 8, %l0";
+ if (sub_reg)
+ *sub_reg = R2;
+ } else {
+ cache_need(2);
+ if (tos->reg >= reg_f0 && tos[-1].reg >= reg_f0 &&
+ REG_NUM(tos->reg) == REG_NUM(tos[-1].reg)-1 &&
+ tos->reg2 == reg_g0 && tos[-1].reg2 == reg_g0)
+ {
+ R1= tos->reg;
+ if (sub_reg)
+ *sub_reg= tos[-1].reg;
+ POP2;
+ POP2;
+ } else {
+ R1= alloc_double(&R2);
+ if (sub_reg)
+ *sub_reg= R2;
+ if (tos->reg >= reg_f0 || tos[-1].reg >= reg_f0)
+ {
+ pop_reg_as(R1);
+ pop_reg_as(R2);
+ } else {
+ /* two normal registers */
+ R3= pop_reg();
+ R4= pop_reg();
+ "st $R3, [%fp+64]";
+ "st $R4, [%fp+68]";
+ "ldd [%fp+64], $R1";
+ free_reg(R3);
+ free_reg(R4);
+ }
+ }
+ }
+leave("pop_double");
+ return R1;
+}
+
+void pop_nop(i)
+int i;
+{
+ const_str_t V1;
+ int j = i;
+
+enter("pop_nop");
+ while (c_count && i) {
+ i--;
+ POP1;
+ free_reg(tos->reg);
+ free_reg(tos->reg2);
+ if (tos->ext)
+ free(tos->ext);
+ POP2;
+ }
+ if (i) {
+ sprintf(V1, "%d", 4*i);
+ if (const13(4*i)) {
+ "inc $V1, %l0";
+ } else {
+ "set $V1, $reg_tmp";
+ "inc %l0, $reg_tmp, %l0";
+ }
+ }
+if (debug) { indent(); fprint(codefile, "\t\t! %dw cache:",j); dump_cache(codefile); }
+leave("pop_nop");
+}
+
+check_cache()
+{
+ int i;
+if (debug)
+ for (i = 0; i < NR_REGS; i++)
+ fprintf(stderr, "%c", reg[i].inuse ? (reg[i].inuse)+48 : '.');
+ fprintf(stderr, "\n");
+}
+
+void flush_cache() /* flush the cache onto the stack */
+{
+enter("flush_cache");
+
+if (debug) { indent(); fprintf(stderr,"flush_cache\n"); }
+ if (c_count)
+ flush_part_cache(c_count, 0, 0, 0);
+
+ /* TEST */
+if (debug)
+ check_cache();
+leave("flush_cache");
+}
+
+void cache_need(n)
+int n;
+{
+enter("cache_need");
+ if (c_count < n)
+ (void) cache_read(n, 0);
+ assert(c_count >= n);
+leave("cache_need");
+}
+
+static int cache_read(n, i)
+int n;
+int i;
+{
+ const_str_t V1;
+ reg_t S1;
+ int j;
+ int old_c_count;
+
+enter("cache_read");
+if (debug) { indent(); fprintf(stderr,"cache_read(%d, %d)\n", n,i); }
+ if (i+c_count<n)
+ {
+ S1= alloc_reg();
+ old_c_count = cache_read(n, i+1);
+
+ sprintf(V1, "%d", (old_c_count-1-i) * 4);
+ "ld [%l0+$V1], $S1";
+ cache[i].reg= S1;
+ cache[i].reg2= reg_g0;
+ cache[i].ext= 0;
+ cache[i].cst= 0;
+ if (!i)
+ {
+ sprintf(V1, "%d", (old_c_count)*4);
+ "add $reg_sp, $V1, $reg_sp";
+ }
+ }
+ else
+ {
+ assert (i);
+ for (j= c_count-1; j>=0; j--)
+ cache[j+i]= cache[j];
+ c_count += i;
+ tos= &cache[c_count-1];
+ old_c_count = i;
+ }
+leave("cache_read");
+ return old_c_count;
+}
+
+static void dump_cache(stream) /* to codefile! */
+File *stream;
+{
+ int i;
+
+ assert (c_count >= 0);
+ for (i = c_count -1; i >= 0; i--) {
+ if (cache[i].ext)
+ fprint(stream, "%s", cache[i].ext);
+ if (cache[i].reg != reg_g0) {
+ if (cache[i].ext)
+ fprint(stream, "+");
+ fprint(stream, "%s", cache[i].reg);
+ if (cache[i].reg2 != reg_g0) {
+ fprint(stream, "+");
+ fprint(stream, "%s", cache[i].reg2);
+ }
+ }
+ if (cache[i].cst || (!cache[i].ext && cache[i].reg == reg_g0)) {
+ if (cache[i].ext || cache[i].reg != reg_g0)
+ fprint(stream, "+");
+ fprint(stream, "%d", cache[i].cst);
+ }
+ fprint(stream, " ");
+ }
+ fprint(stream, "\n");
+if (debug) check_cache();
+}
+
+void dup_tos(n)
+int n;
+{
+ reg_t a;
+ int i;
+ const_str_t i_str;
+
+enter("dup_tos");
+ for (i = 0;i < n; i++) {
+ INC_TOS;
+ tos->reg = reg_g0;
+ tos->reg2 = reg_g0;
+ tos->cst = 0;
+ tos->ext = 0;
+ if (c_count > n) {
+ char *ext;
+
+ *tos = tos[-n];
+ if (tos->ext)
+ {
+ ext= malloc(strlen(tos->ext)+1);
+ strcpy(ext, tos->ext);
+ tos->ext= ext;
+ }
+ soft_alloc_reg(tos->reg);
+ soft_alloc_reg(tos->reg2);
+ } else {
+ a= alloc_reg();
+ sprintf(i_str, "%d", (n-c_count)*4);
+ "ld [$reg_sp+$i_str], $a";
+ tos->reg = a;
+ }
+ }
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("dup_tos");
+}
--- /dev/null
+C_con_scon.c
+C_cst.c
+C_mes_begin.c
+C_mes_end.c
+C_rom_scon.c
+misc.c
+ms_reg.c
--- /dev/null
+#define CODE_EXPANDER
+#include <em.h>
+#include "mach.h"
+#include "back.h"
+
+C_con_scon( s, n)
+char *s;
+arith n;
+{
+ switchseg( SEGCON);
+ dump_label();
+
+ con_str( s, n);
+}
--- /dev/null
+#define CODE_EXPANDER
+#include <em.h>
+
+/* in ms_reg.c
+C_cst( l)
+arith l;
+{
+} */
--- /dev/null
+#define CODE_EXPANDER
+#include <em.h>
+
+/* in ms_reg.c
+C_mes_begin( ms)
+int ms;
+{
+} */
--- /dev/null
+#define CODE_EXPANDER
+#include <em.h>
+
+/* in ms_reg.c
+C_mes_end()
+{
+} */
--- /dev/null
+#define CODE_EXPANDER
+#include <em.h>
+#include "mach.h"
+#include "back.h"
+
+C_rom_scon( s, n)
+char *s;
+arith n;
+{
+ switchseg( SEGROM);
+ dump_label();
+
+ rom_str( s,n);
+}
--- /dev/null
+/*
+misc.c
+*/
+
+#include "mach.h"
+
+int power_of_2(n, ref_exp)
+int n, *ref_exp;
+{
+ int exp;
+
+ exp= 0;
+ if (n<0)
+ n= -n;
+
+ if (!n)
+ return 0;
+
+ while (!(n % 2))
+ {
+ n= n/2;
+ exp++;
+ }
+ if (n != 1)
+ return 0;
+
+ if (ref_exp)
+ *ref_exp= exp;
+ return 1;
+}
+
+int uns_power_of_2(n, ref_exp)
+unsigned n, *ref_exp;
+{
+ int exp;
+
+ exp= 0;
+
+ if (!n)
+ return 0;
+
+ while (!(n % 2))
+ {
+ n= n/2;
+ exp++;
+ }
+ if (n != 1)
+ return 0;
+
+ if (ref_exp)
+ *ref_exp= exp;
+ return 1;
+}
+
--- /dev/null
+/* catch register messages. BEWARE: code uses plain printf's (fprint's)
+ * to generate code. This is not compatible with the usual procedure
+ * used in the EM_table
+ */
+
+#define CODE_EXPANDER
+#include <em.h>
+#include <em_reg.h>
+#include <em_mes.h>
+#include "push_pop.h"
+#include "mach.h"
+#include <stdio.h>
+
+#define MAX_NR_REGS 12
+#define MAX_NR_FLTS MAX_NR_FLT_REGS /* depends on using float or doubles */
+
+#define RM_OFFSET 0
+#define RM_SIZE 1
+#define RM_TYPE 2
+#define RM_COUNT 3
+
+typedef struct reg_info {
+ int offset;
+ int size; /* 4 or 8 */
+ int pri;
+ reg_t reg, reg2; /* reg2 used for doubles only */
+} reg_info;
+
+reg_info reg_dat[MAX_NR_REGS], flt_dat[MAX_NR_FLTS];
+
+int current_reg_mes[RM_COUNT+4];
+
+int in_reg_mes = 0; /* boolean */
+int reg_mes_nr;
+
+int worst_reg_pri, worst_flt_pri; /* reset by C_prolog (to some large number) */
+int nr_reg_vars, nr_flt_vars; /* dito (both to 0) */
+
+init_reg_man()
+{
+ worst_reg_pri = worst_flt_pri = (unsigned)-1/2;
+ nr_reg_vars = nr_flt_vars = 0;
+}
+
+reg_t my_alloc_reg(pri,loc)
+int pri, *loc;
+{
+ reg_t S1;
+ int i;
+
+ if ((S1 = alloc_reg_var()) == NULL)
+ if (current_reg_mes[RM_COUNT] > worst_reg_pri) {
+ for (i = 0; i < nr_reg_vars; i++)
+ if (reg_dat[i].pri <= worst_reg_pri) {
+ *loc = i;
+ S1 = reg_dat[i].reg;
+ break;
+ }
+ worst_reg_pri = (unsigned)-1/2;
+ for (i = 0; i < nr_reg_vars; i++)
+ if (reg_dat[i].pri <= worst_reg_pri)
+ worst_reg_pri = reg_dat[i].pri;
+ } else
+ return NULL; /* SORRY, FULL HOUSE! */
+ else
+ *loc = nr_reg_vars++;
+
+ return S1;
+}
+
+reg_t my_alloc_double(pri,loc,r2)
+int pri, *loc;
+reg_t *r2;
+/* implementation note: my_alloc_double only reclaims other doubles
+ * when a better candidate is given. It never reclaims floats, even if
+ * the current double is a mich better candidate.
+ */
+{
+ reg_t S1;
+ int i;
+
+ if ((S1 = alloc_double_var(r2)) == NULL)
+ if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
+ for (i = 0; i < nr_flt_vars; i++)
+ if (flt_dat[i].pri <= worst_flt_pri &&
+ flt_dat[i].size == EM_DSIZE) {
+ *loc = i;
+ S1 = flt_dat[i].reg;
+ *r2 = flt_dat[i].reg2;
+ break;
+ }
+ worst_flt_pri = (unsigned)-1/2;
+ for (i = 0; i < nr_flt_vars; i++)
+ if (flt_dat[i].pri < worst_flt_pri)
+ worst_flt_pri = flt_dat[i].pri;
+ } else
+ return NULL; /* SORRY, FULL HOUSE! */
+ else
+ *loc = nr_flt_vars++;
+
+ return S1;
+}
+
+reg_t my_alloc_float(pri,loc)
+int pri, *loc;
+/* just as for my_alloc_double, my_alloc_float never reclaims a double,
+ * even though this me be useful and easy. Sorry.
+ */
+{
+ reg_t S1;
+ int i;
+
+ if ((S1 = alloc_float_var()) == NULL)
+ if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
+ for (i = 0; i < nr_flt_vars; i++)
+ if (flt_dat[i].pri <= worst_flt_pri &&
+ flt_dat[i].size == EM_WSIZE) {
+ *loc = i;
+ S1 = flt_dat[i].reg;
+ break;
+ }
+ worst_flt_pri = (unsigned)-1/2;
+ for (i = 0; i < nr_flt_vars; i++)
+ if (flt_dat[i].pri <= worst_flt_pri)
+ worst_flt_pri = flt_dat[i].pri;
+ } else
+ return NULL; /* SORRY, FULL HOUSE! */
+ else
+ *loc = nr_flt_vars++;
+
+ return S1;
+}
+
+free_all_reg_vars()
+{
+ int i;
+
+ for (i = 0; i < nr_reg_vars; i++)
+ free_reg(reg_dat[i].reg);
+ for (i = 0; i < nr_flt_vars; i++)
+ switch (flt_dat[i].size) {
+ case EM_WSIZE: free_reg(flt_dat[i].reg); break;
+ case EM_DSIZE: free_double_reg(flt_dat[i].reg); break;
+ }
+ check_cache();
+}
+
+alloc_all_reg_vars()
+{
+ int i;
+
+ for (i = 0; i < nr_reg_vars; i++)
+ forced_alloc_reg(reg_dat[i].reg);
+ for (i = 0; i < nr_flt_vars; i++)
+ switch (flt_dat[i].size) {
+ case EM_WSIZE: forced_alloc_reg(flt_dat[i].reg); break;
+ case EM_DSIZE:
+ forced_alloc_reg(flt_dat[i].reg);
+ forced_alloc_reg(flt_dat[i].reg2);
+ break;
+ }
+ check_cache();
+}
+
+params_to_regs() /* copy required parameters to registers */
+{
+ int i, j;
+
+ for (i = 0; i < nr_reg_vars; i++)
+ if (reg_dat[i].offset > 0)
+ fprint(codefile, "ld [%%l1+%d], %s\n",
+ reg_dat[i].offset, reg_dat[i].reg);
+
+ for (i = 0; i < nr_flt_vars; i++)
+ if (flt_dat[i].offset > 0)
+ {
+ fprint(codefile, "ld [%%l1+%d], %s\n",
+ flt_dat[i].offset, flt_dat[i].reg);
+ if (flt_dat[i].size == EM_DSIZE)
+ fprint(codefile, "ld [%%l1+%d], %s\n",
+ flt_dat[i].offset + 4, flt_dat[i].reg2);
+ }
+}
+
+cmp_flt_dat(e1, e2)
+reg_info *e1, *e2;
+{
+ return (e1->offset - e2->offset);
+}
+
+save_float_regs()
+{
+ int i;
+ int offset;
+
+ qsort(flt_dat, nr_flt_vars, sizeof(flt_dat[0]), cmp_flt_dat);
+ for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
+ if ((i+1 < nr_flt_vars &&
+ flt_dat[i].offset == flt_dat[i+1].offset-4 &&
+ flt_dat[i].size == EM_FSIZE &&
+ flt_dat[i+1].size == EM_FSIZE)
+ || (flt_dat[i].size == EM_DSIZE)) {
+ fprint(codefile, "std %s, [%%fp + %d]\n",
+ flt_dat[i].reg, FLTSAV_OFFSET + offset);
+ if (flt_dat[i].size != EM_DSIZE)
+ ++i;
+ } else
+ fprint(codefile, "st %s, [%%fp + %d]\n",
+ flt_dat[i].reg, FLTSAV_OFFSET + offset);
+}
+
+load_float_regs()
+{
+ int i;
+ int offset;
+
+ for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
+ if ((i+1 < nr_flt_vars &&
+ flt_dat[i].offset == flt_dat[i+1].offset-4 &&
+ flt_dat[i].size == EM_FSIZE &&
+ flt_dat[i+1].size == EM_FSIZE)
+ || (flt_dat[i].size == EM_DSIZE)) {
+ fprint(codefile, "ldd [%%fp + %d], %s\n",
+ FLTSAV_OFFSET + offset, flt_dat[i].reg);
+ if (flt_dat[i].size != EM_DSIZE)
+ ++i;
+ } else
+ fprint(codefile, "ld [%%fp + %d], %s\n",
+ FLTSAV_OFFSET + offset, flt_dat[i].reg);
+
+}
+
+C_mes_begin( ms)
+int ms;
+{
+ reg_mes_nr = 0;
+ in_reg_mes = (ms == ms_reg);
+ if (ms == ms_gto)
+ fprint(codefile, "ta 3\n");
+}
+
+C_mes_end()
+{
+ int pos;
+ reg_t S1, S2;
+
+ if (!in_reg_mes) /* end of some other mes */
+ return;
+ if (reg_mes_nr == 0) { /* end of reg_mes's */
+ save_float_regs();
+ params_to_regs();
+ if (debug)
+ dump_reg_tabs(codefile);
+ return;
+ }
+ if (current_reg_mes[RM_COUNT] == 0) /* never used, so ignore */
+ return;
+ if (current_reg_mes[RM_OFFSET] >= 0)
+ current_reg_mes[RM_OFFSET] += EM_BSIZE;
+ if (debug)
+ fprint(codefile, "\t\t! Got reg_mes: %d %d %d %d\n",
+ current_reg_mes[0], current_reg_mes[1],
+ current_reg_mes[2], current_reg_mes[3]);
+ if (current_reg_mes[RM_TYPE] == reg_float) {
+ switch(current_reg_mes[RM_SIZE]) {
+ case EM_WSIZE :
+ if ((S1 = my_alloc_float(current_reg_mes[RM_COUNT], &pos))
+ == NULL)
+ return;
+ break;
+ case EM_DSIZE:
+ if ((S1 = my_alloc_double(current_reg_mes[RM_COUNT], &pos, &S2))
+ == NULL)
+ return;
+ flt_dat[pos].reg2 = S2;
+ default: break;
+ }
+ flt_dat[pos].offset = current_reg_mes[RM_OFFSET];
+ flt_dat[pos].size = current_reg_mes[RM_SIZE];
+ flt_dat[pos].pri = current_reg_mes[RM_COUNT];
+ flt_dat[pos].reg = S1;
+ } else {
+ if (current_reg_mes[RM_SIZE] != EM_WSIZE)
+ return; /* IGNORE THESE */
+ if ((S1 = my_alloc_reg(current_reg_mes[RM_COUNT], &pos)) == NULL)
+ return; /* SORRY, FULL HOUSE! */
+
+ reg_dat[pos].offset = current_reg_mes[RM_OFFSET];
+ reg_dat[pos].size = current_reg_mes[RM_SIZE];
+ reg_dat[pos].pri = current_reg_mes[RM_COUNT];
+ reg_dat[pos].reg = S1;
+ }
+}
+
+C_cst( l)
+arith l;
+{
+ if (in_reg_mes)
+ current_reg_mes[reg_mes_nr++] = l;
+}
+
+dump_reg_tabs(stream)
+FILE *stream;
+{
+ int i;
+
+ fprint(stream, "!offset\tsize\tname (%d regvars)\n", nr_reg_vars);
+ for (i = 0; i < nr_reg_vars; i++)
+ fprint(stream, "! %d\t%d\t%s\n", reg_dat[i].offset, reg_dat[i].size,
+ reg_dat[i].reg);
+
+ fprint(stream, "!offset\tsize\tname (%d fltvars)\n", nr_flt_vars);
+ for (i = 0; i < nr_flt_vars; i++)
+ fprint(stream, "! %d\t%d\t%s\n", flt_dat[i].offset, flt_dat[i].size,
+ flt_dat[i].reg);
+}
+
+reg_t find_local(offset, reg2) /* WARNING: no size checking here! */
+int offset;
+reg_t *reg2;
+{
+ int i;
+
+ if (reg2)
+ *reg2 = NULL;
+ for (i = 0; i < nr_reg_vars; i++)
+ if (reg_dat[i].offset == offset)
+ return reg_dat[i].reg;
+
+ for (i = 0; i < nr_flt_vars; i++)
+ if (flt_dat[i].offset == offset) {
+ if (flt_dat[i].size == EM_DSIZE)
+ if (reg2)
+ *reg2 = flt_dat[i].reg2;
+ return flt_dat[i].reg;
+ }
+ return NULL;
+}
--- /dev/null
+# dit sed script zet regels van het type "sll $a, $$, $44" om in
+# fprint(codefile, "sll %s, $, $44\n", a);
+# en meer....
+# Usage: sed -f $0 < EM_table.x > EM_table
+# remember to include special thingies in "mach.h"
+#n
+s/==>/&\
+code_combiner(/
+s/\.[ ]*$/)\
+&/
+/^[ ]*"/{
+s/%/%%/g
+i\
+fprint ( codefile,
+s/\$\$/__NEVER_USED__/g
+s/\$\([0-9][0-9]*\)/__NEVER_USED__\1/g
+s/\$\$/%a/g
+:a
+s/\([^\$]*\)\$\([^\$][A-Za-z0-9_]*\)\(.*\)/\1%s\3\
+\2/
+t a
+s/\n/,/g
+s/__NEVER_USED__/$/g
+s/";/"/
+s/\([^"]*"[^"]*\)"\(.*\)/\1\\n"\2/
+p
+i\
+);
+D
+}
--- /dev/null
+#define CODE_EXPANDER
+#include "mach.h"
+#include <back.h>
+#include <system.h>
+
+
+#ifdef DEBUG
+arg_error( s, arg)
+char *s;
+int arg;
+{
+ fprint( STDERR, "arg_error %s %d\n", s, arg);
+}
+#endif
+
+
+/*
+do_open( filename)
+char *filename;
+{
+ if ( filename == (char *)0 || !sys_open( filename, OP_WRITE, &codefile))
+ return( 0);
+
+ fprint( codefile, ".sect .text; .sect .rom; .sect .data; .sect .bss\n");
+ return( 1);
+}
+*/
+
+#define IEEEFLOAT
+#define FL_MSL_AT_LOW_ADDRESS 1
+#define FL_MSW_AT_LOW_ADDRESS 1
+#define FL_MSB_AT_LOW_ADDRESS 1
+#include <con_float>
+
+#include <cache.c>
--- /dev/null
+/*
+mach.h
+*/
+
+#ifndef MACH_H
+#define MACH_H
+
+#include "ctype.h"
+#include "mach_em.h"
+#include "push_pop.h"
+#include "ms_reg.h"
+#include "misc.h"
+
+#if RESOLV_debug
+ #define debug 0
+#else
+ extern int debug;
+#endif
+
+#endif /* MACH_H */
--- /dev/null
+#define DEBUG 1
+#include <sun4/asm_linkage.h>
+
+#define BYTES_REVERSED
+#define WORDS_REVERSED
+
+#define ONE_BYTE int
+#define TWO_BYTES int
+#define FOUR_BYTES long
+
+#define EM_WSIZE 4
+#define EM_PSIZE 4
+#define EM_FSIZE 4
+#define EM_DSIZE 8
+#define EM_BSIZE REGSAV
+
+#define BSS_INIT 0
+
+#define NAME_FMT "_%s"
+#define DNAM_FMT "_%s"
+#define DLB_FMT "L_%ld"
+#define ILB_FMT "L%x_%lx"
+#define HOL_FMT "hol%d"
+#define STR_FMT ".ascii\t"
+
+#define GENLAB 'L'
+
+#define ALIGN_FMT ".align 4\n"
+
+#define BYTE_FMT ".byte %ld\n"
+#define WORD_FMT ".half %ld\n"
+#define LONG_FMT ".word %ld\n"
+#define BSS_FMT ".skip %ld\n"
+
+#define SEGTXT_FMT ".seg \"text\"\n"
+#define SEGDAT_FMT ".seg \"data\"\n"
+#define SEGBSS_FMT ".seg \"bss\"\n"
+
+#define SYMBOL_DEF_FMT "%s:\n"
+#define GLOBAL_FMT ".global %s\n"
+#define COMM_FMT ".reserve %s, %ld, \"bss\"\n"
+#define LOCAL_FMT ""
+
+#define RELOC1_FMT "ONLY LONGS CAN BE RELOCATED!"
+#define RELOC2_FMT "ONLY LONGS CAN BE RELOCATED!"
+#define RELOC4_FMT ".seg \"data\"\n.align 4\n.word %s+%d\n"
+
+#define ALIGN_GAP 4
+#define FLOATTRANS 8
+#define MAX_NR_FLT_REGS 16
+#define FLTSAV (MAX_NR_FLT_REGS * 4)
+#define FLTSAV_OFFSET (WINDOWSIZE + FLOATTRANS)
+#define REGSAV (WINDOWSIZE + FLOATTRANS + ALIGN_GAP + FLTSAV)
+
+#define MATH_DIVIDE 1
+
+#ifndef DEBUG
+#define arg_error(s,i)
+#endif
--- /dev/null
+/*
+misc.h
+*/
+
+#ifndef MISC_H
+#define MISC_H
+
+_PROTOTYPE( int power_of_2, (int n, int *ref_exp));
+
+#endif /* MISC_H */
+
--- /dev/null
+/* ms_reg.h */
+
+#ifndef MS_REG_H
+#define MS_REG_H
+
+#include "push_pop.h"
+
+_PROTOTYPE(reg_t find_local, (int, reg_t*));
+
+#endif
--- /dev/null
+# $Header$
+
+#PARAMS do not remove this line!
+
+MACH = sparc
+OBJ = as
+SRC_DIR = $(SRC_HOME)/mach/$(MACH)/ce
+
+CEG = $(TARGET_HOME)/lib.bin/ceg/util
+
+all:
+ ( cd $(SRC_DIR); make )
+ make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH)
+
+install:
+ ( cd $(SRC_DIR); make )
+ -mkdir $(TARGET_HOME)/lib.bin/sparc
+ make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) install
+
+cmp:
+ ( cd $(SRC_DIR); make )
+ -make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) cmp
+
+pr:
+ @pr $(SRC_DIR)/proto.make $(SRC_DIR)/EM_table.x $(SRC_DIR)/mach.h \
+ $(SRC_DIR)/mach.c $(SRC_DIR)/cache.c.x
+
+opr:
+ make pr | opr
+
+# total cleanup
+clean:
+ make -f $(CEG)/make_asobj "OBJ="$(OBJ) clean
+
+# only remove ce, ceg, and back directories
+dclean:
+ make -f $(CEG)/make_asobj "OBJ="$(OBJ) dclean
--- /dev/null
+/*
+push_pop.h
+*/
+
+#ifndef PUSH_POP_H
+#define PUSH_POP_H
+
+#include "back.h"
+
+#define NR_REGS 64
+
+typedef char *reg_t;
+
+typedef struct cache_elt {
+ reg_t reg, reg2;
+ char *ext;
+ arith cst;
+} cache_elt;
+
+#define REG_NUM(r) (((char(*)[8])(r))-regnam)
+
+#define T_cst 1
+#define T_ext 2
+#define T_reg 4
+#define T_float 8
+#define T_reg2 16
+#define T_float2 32
+
+typedef char const_str_t[NR_REGS];
+
+extern reg_t reg_g0, reg_g1, reg_g2, reg_g3, reg_g4, reg_g5, reg_g6, reg_g7;
+extern reg_t reg_i0, reg_i1, reg_i2, reg_i3, reg_i4, reg_i5, reg_i6, reg_i7;
+extern reg_t reg_l0, reg_l1, reg_l2, reg_l3, reg_l4, reg_l5, reg_l6, reg_l7;
+extern reg_t reg_o0, reg_o1, reg_o2, reg_o3, reg_o4, reg_o5, reg_o6, reg_o7;
+extern reg_t reg_f0;
+extern reg_t reg_sp, reg_lb, reg_gap;
+extern reg_t reg_tmp;
+
+#ifdef __STDC__
+#define _PROTOTYPE(x,y) x y
+#else
+#define _PROTOTYPE(x,y) x()
+#endif
+
+_PROTOTYPE(int const13, (int));
+_PROTOTYPE(void init_cache, (void));
+_PROTOTYPE(void free_reg, (reg_t));
+_PROTOTYPE(void free_double, (reg_t)); /* ..._reg */
+_PROTOTYPE(void forced_alloc_reg, (reg_t));
+_PROTOTYPE(void soft_alloc_reg, (reg_t));
+_PROTOTYPE(void change_reg, (reg_t));
+_PROTOTYPE(int type_of_tos, (void));
+_PROTOTYPE(void inc_tos, (arith));
+_PROTOTYPE(void inc_tos_reg, (reg_t));
+_PROTOTYPE(void push_const, (arith));
+_PROTOTYPE(void push_reg, (reg_t));
+_PROTOTYPE(void push_ext, (char *));
+_PROTOTYPE(void flush_cache, (void));
+static _PROTOTYPE(void flush_part_cache, (int c, int r, int f, int d));
+static _PROTOTYPE(void subst_reg, (reg_t, reg_t));
+_PROTOTYPE(void cache_need, (int));
+static _PROTOTYPE(int cache_read, (int n, int i));
+static _PROTOTYPE(void dump_cache, (File *stream));
+_PROTOTYPE(void pop_nop, (int));
+static _PROTOTYPE(void panic, (char*));
+
+_PROTOTYPE(reg_t alloc_reg, (void));
+_PROTOTYPE(reg_t alloc_reg_var, (void));
+_PROTOTYPE(reg_t alloc_float, (void));
+_PROTOTYPE(reg_t alloc_float_var, (void));
+_PROTOTYPE(reg_t alloc_double, (reg_t *sub_reg));
+_PROTOTYPE(reg_t alloc_double_var, (reg_t *sub_reg));
+_PROTOTYPE(reg_t pop_reg, (void));
+_PROTOTYPE(reg_t pop_reg_c13, (char*));
+_PROTOTYPE(reg_t pop_reg_reg, (reg_t*));
+_PROTOTYPE(reg_t pop_float, (void));
+_PROTOTYPE(reg_t pop_double, (reg_t *sub_reg));
+_PROTOTYPE(void pop_reg_as, (reg_t r));
+static _PROTOTYPE(reg_t top_reg, (void));
+static _PROTOTYPE(reg_t top_reg_c13, (char*));
+
+_PROTOTYPE(arith pop_const, (char *n_str));
+_PROTOTYPE(arith top_const, (void));
+_PROTOTYPE(void dup_tos, (int n));
+_PROTOTYPE(void exg_top, (int n));
+
+#define code_combiner(x) x
+
+#endif /* PUSH_POP_H */
--- /dev/null
+LIST
+libmon_s.a
+head_em.s
+SYS.h
+syscall.h
--- /dev/null
+libmon_s.a
+_alarm.c
+_brk.s
+_close.s
+_creat.s
+_dup.s
+_dup2.s
+_execl.c
+_execve.s
+_exit.s
+_fork.s
+_fstat.s
+_ftime.c
+_getpid.s
+_getrusage.s
+_gettimday.s
+_gtty.c
+_ioctl.s
+_kill.s
+_link.s
+_lseek.s
+_open.s
+_pause.c
+_pipe.s
+_read.s
+_setitimer.s
+_sigblock.s
+_sigpause.s
+_sigsetmask.s
+_sigvec.c
+_sigvecscall.s
+_times.c
+_unlink.s
+_wait4.s
+_write.s
+accept.s
+access.s
+acct.s
+adjtime.s
+alarm.c
+bind.s
+brk.s
+cerror.s
+chdir.s
+chmod.s
+chown.s
+chroot.s
+cleanup.c
+close.s
+connect.s
+creat.s
+dup.s
+dup2.s
+execl.c
+execle.c
+execv.c
+execve.s
+exit.c
+fchdir.s
+fchmod.s
+fchown.s
+fchroot.s
+fcntl.s
+fif.s
+flock.s
+fork.s
+fstat.s
+fstatfs.s
+fsync.s
+ftime.c
+ftruncate.s
+getdents.s
+getdirent.s
+getdomnam.s
+getdtabsiz.s
+getegid.s
+geteuid.s
+getgid.s
+getgroups.s
+gethostname.s
+getitimer.s
+getmsg.s
+getpeername.s
+getpgrp.s
+getpid.s
+getpriority.s
+getrlimit.s
+getrusage.s
+getsockname.s
+getsockopt.s
+gettimeofday.s
+getuid.s
+gtty.c
+ioctl.s
+kill.s
+killpg.s
+link.s
+listen.s
+lockf.c
+lseek.s
+lstat.s
+mincore.s
+mkdir.s
+mknod.s
+mmap.s
+mount.s
+mprotect.s
+msync.s
+munmap.s
+nfssvc.s
+nice.c
+open.s
+pause.c
+pipe.s
+plock.c
+poll.s
+profil.s
+ptrace.s
+putmsg.s
+quotactl.s
+read.s
+readlink.s
+readv.s
+reboot.s
+recv.s
+recvfrom.s
+recvmsg.s
+rename.s
+rmdir.s
+sbrk.s
+select.s
+send.s
+sendmsg.s
+sendto.s
+setdomnam.s
+setgid.c
+setgroups.s
+sethostname.s
+setitimer.s
+setpgrp.s
+setpriority.s
+setregid.s
+setreuid.s
+setrlimit.s
+setsockopt.s
+settimeofday.s
+setuid.c
+shutdown.s
+sigblock.s
+signal.c
+sigpause.s
+sigsetmask.s
+sigstack.s
+sigtramp.s
+sigvec.c
+sigvec_scall.s
+socket.s
+socketpair.s
+stat.s
+statfs.s
+stime.c
+stty.c
+swapon.s
+symlink.s
+tell.c
+time.c
+times.c
+truncate.s
+ulimit.c
+umask.s
+uname.c
+unlink.s
+unmount.s
+utime.c
+utimes.s
+vadvise.s
+vfork.s
+wait4.s
+write.s
+writev.s
--- /dev/null
+/*
+SYS.h
+*/
+
+#ifndef SYS_H
+#define SYS_H
+
+#include <syscall.h>
+
+#define SYS_call_0(x) \
+ LABEL_(x); \
+ BODY(x)
+
+#define _SYS_call_0(x) \
+ LABEL__(x); \
+ LABEL(x); \
+ BODY(x)
+
+#define SYS_call_1(x) \
+ LABEL_(x); \
+ ENTRY1; \
+ BODY(x)
+
+#define _SYS_call_1(x) \
+ LABEL__(x); \
+ ENTRY1; \
+ LABEL(x); \
+ BODY(x)
+
+#define SYS_call_2(x) \
+ LABEL_(x); \
+ ENTRY2; \
+ BODY(x)
+
+#define _SYS_call_2(x) \
+ LABEL__(x); \
+ ENTRY2; \
+ LABEL(x); \
+ BODY(x)
+
+#define SYS_call_3(x) \
+ LABEL_(x); \
+ ENTRY3; \
+ BODY(x)
+
+#define _SYS_call_3(x) \
+ LABEL__(x); \
+ ENTRY3; \
+ LABEL(x); \
+ BODY(x)
+
+#define SYS_call_4(x) \
+ LABEL_(x); \
+ ENTRY4; \
+ BODY(x)
+
+#define _SYS_call_4(x) \
+ LABEL__(x); \
+ ENTRY4; \
+ LABEL(x); \
+ BODY(x)
+
+#define SYS_call_5(x) \
+ LABEL_(x); \
+ ENTRY5; \
+ BODY(x)
+
+#define _SYS_call_5(x) \
+ LABEL__(x); \
+ ENTRY5; \
+ LABEL(x); \
+ BODY(x)
+
+#define SYS_call_6(x) \
+ LABEL_(x); \
+ ENTRY6; \
+ BODY(x)
+
+#define _SYS_call_6(x) \
+ LABEL__(x); \
+ ENTRY6; \
+ LABEL(x); \
+ BODY(x)
+
+#define BODY(x) \
+ sys_call(x); \
+ ta %g0; \
+ bgeu 0f; \
+ sethi %hi(cerror), %o5; \
+ or %o5, %lo(cerror), %o5; \
+ jmp %o5; \
+ nop; \
+0:; \
+ retl; \
+ nop
+
+#if __STDC__
+#define LABEL_(x) \
+ .global _ ## x; \
+ _ ## x:
+#define LABEL__(x) \
+ .global __ ## x; \
+ __ ## x:
+#else
+#define LABEL_(x) \
+ .global _/**/x; \
+ _/**/x:
+#define LABEL__(x) \
+ .global __/**/x; \
+ __/**/x:
+#endif
+#define LABEL(x) \
+ .global x; \
+ x:
+
+#define ENTRY1 \
+ ld [%l0], %o0 \
+
+#define ENTRY2 \
+ ENTRY1; \
+ ld [%l0+4], %o1 \
+
+#define ENTRY3 \
+ ENTRY2; \
+ ld [%l0+8], %o2 \
+
+#define ENTRY4 \
+ ENTRY3; \
+ ld [%l0+12], %o3 \
+
+#define ENTRY5 \
+ ENTRY4; \
+ ld [%l0+16], %o4 \
+
+#define ENTRY6 \
+ ENTRY5; \
+ ld [%l0+20], %o5 \
+
+#if __STDC__
+#define sys_call(x) \
+ mov SYS_ ## x, %g1
+#else
+#define sys_call(x) \
+ mov SYS_/**/x, %g1
+#endif
+
+#endif /* SYS_H */
--- /dev/null
+unsigned
+_alarm(n)
+ unsigned n;
+{
+ struct { long l1,l2,l3,l4; } t1,t2;
+ t1.l1 = 0;
+ t1.l2 = 0;
+ t1.l4 = 0;
+ t1.l3 = n;
+ if (_setitimer(0,&t1,&t2) < 0) return -1;
+ if (t2.l4) t2.l3++;
+ return t2.l3;
+}
--- /dev/null
+.global cerror, __brk, __sbrk, limhp, brk, sbrk
+
+__brk:
+ ld [%l0], %o0
+brk: inc 7, %o0
+ andn %o0, 7, %o0
+ mov %o0, %o2
+ mov 0x11, %g1
+ ta %g0
+ nop
+ bgeu 0f
+ nop
+ set cerror, %o5
+ jmp %o5
+ nop
+0:
+ set limhp, %g1
+ st %o2, [%g1]
+ retl
+ nop
+
+
+__sbrk:
+ ld [%l0], %o0
+sbrk: inc 7, %o0
+ andn %o0, 7, %o0
+ set limhp, %o1
+ ld [%o1], %o2
+ inc 7, %o2
+ andn %o2, 7, %o3
+ add %o3, %o0, %o0
+ mov %o0, %o4
+ mov 0x11, %g1
+ ta %g0
+ nop
+ bgeu 0f
+ nop
+ set cerror, %o5
+ jmp %o5
+ nop
+0:
+ set limhp, %g1
+ st %o4, [%g1]
+ mov %o3, %o0
+ retl
+ nop
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_1(close)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_2(creat)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_1(dup)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_2(dup2)
--- /dev/null
+_execl(name,args)
+ char *name;
+ int args;
+{
+ extern char **environ;
+
+ _execve(name,&args,environ);
+}
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(execve)
--- /dev/null
+#include "SYS.h"
+
+.global __exit
+__exit:
+ ld [%l0], %o0
+ set SYS_exit, %g1
+ ta %g0
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_0(fork)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_2(fstat)
--- /dev/null
+#include <sys/types.h>
+
+_ftime(p)
+ struct { time_t time; unsigned short millitm;
+ short timezone; short dstflag; } *p;
+{
+ struct { long l1,l2; } t1,t2;
+
+ if (_gettimeofday(&t1,&t2) < 0) return -1;
+ p->time = t1.l1;
+ p->millitm = t1.l2/1000;
+ p->dstflag = t2.l2;
+ p->timezone = t2.l1;
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_0(getpid)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_2(getrusage)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_2(gettimeofday)
--- /dev/null
+#include <sgtty.h>
+int
+_gtty(fildes,argp)
+ int fildes ;
+ struct sgttyb *argp ;
+{
+ return _ioctl(fildes,TIOCGETP,argp) ;
+}
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(ioctl)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_2(kill)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_2(link)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(lseek)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(open)
--- /dev/null
+_pause() {
+ _sigpause(_sigblock());
+}
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_1(pipe)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(read)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(setitimer)
+
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(sigblock)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_1(sigpause)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_1(sigsetmask)
--- /dev/null
+#include "syscall.h"
+#include <errno.h>
+struct sigvec { int (*handler)(); int mask,flags; };
+int (*(_sigfunc[32]))();
+extern int _sigtramp();
+extern int errno;
+
+sigvec(sig,vec,ovec)
+ register struct sigvec *vec;
+ struct sigvec *ovec;
+{
+ struct sigvec tmp;
+ int (*old)();
+
+ if ((unsigned) sig >= 32) {
+ errno = EINVAL;
+ return -1;
+ }
+ old = _sigfunc[sig];
+ if (vec) {
+ tmp = *vec;
+ vec = &tmp;
+ if (vec->handler && vec->handler != (int (*)()) 1) {
+ _sigfunc[sig] = vec->handler;
+ vec->handler = _sigtramp;
+ }
+ }
+ if (_sigvec_scall(sig,vec,ovec) < 0) {
+ _sigfunc[sig] = old;
+ return -1;
+ }
+ if (ovec && ovec->handler == _sigtramp) {
+ ovec->handler = old;
+ }
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+#define SYS_sigvec_scall SYS_sigvec
+
+_SYS_call_3(sigvec_scall)
--- /dev/null
+#include <sys/types.h>
+
+#define Xval(xx) ((xx).l1*60+(xx).l2/(100000/6))
+
+_times(bp)
+ struct { time_t l1,l2,l3,l4;} *bp;
+{
+ struct { struct { long l1,l2; }s1,s2; long x[20]; } t;
+ if (_getrusage(0,&t) < 0) return -1;
+ bp->l1 = Xval(t.s1);
+ bp->l2 = Xval(t.s2);
+ if (_getrusage(-1,&t) < 0) return -1;
+ bp->l3 = Xval(t.s1);
+ bp->l4 = Xval(t.s2);
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_1(unlink)
--- /dev/null
+#include "SYS.h"
+
+.global __wait, __wait3
+
+__wait:
+ mov 0, %o0
+ ld [%l0], %o1
+ mov 0, %o2
+ b wait4
+ mov 0, %o3
+
+__wait3:
+ ld [%l0+8], %o3
+ ld [%l0+4], %o2
+ ld [%l0], %o1
+ b wait4
+ mov 0, %o0
+
+_SYS_call_4(wait4)
--- /dev/null
+#include "SYS.h"
+
+_SYS_call_3(write)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(accept)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(access)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(acct)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(adjtime)
--- /dev/null
+unsigned
+alarm(n)
+ unsigned n;
+{
+ struct { long l1,l2,l3,l4; } t1,t2;
+ t1.l1 = 0;
+ t1.l2 = 0;
+ t1.l4 = 0;
+ t1.l3 = n;
+ if (setitimer(0,&t1,&t2) < 0) return -1;
+ if (t2.l4) t2.l3++;
+ return t2.l3;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(bind)
+
--- /dev/null
+.global _brk, __brk
+
+_brk:
+ set __brk,%o7
+ jmp %o7
+ nop
--- /dev/null
+.global _errno
+.global cerror
+
+cerror:
+ set _errno, %o5
+ st %o0, [%o5]
+ set -1, %o0
+ retl
+ nop
+
+.seg "data"
+_errno:
+ .long 0
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(chdir)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(chmod)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(chown)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(chroot)
--- /dev/null
+_cleanup() { }
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(close)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(connect)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(creat)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(dup)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(dup2)
--- /dev/null
+execl(name,args)
+ char *name;
+ int args;
+{
+ extern char **environ;
+
+ execve(name,&args,environ);
+}
--- /dev/null
+execle(name,args)
+ char *name;
+ char *args;
+{
+ char **p = &args;
+ while (*p++) ;
+
+ execve(name,&args,*p);
+}
--- /dev/null
+execv(name,args)
+ char *name;
+ char **args;
+{
+ extern char **environ;
+ execve(name,args,environ);
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(execve)
--- /dev/null
+exit(n)
+{
+ _cleanup();
+ _exit(n);
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(fchdir)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(fchmod)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(fchown)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(fchroot)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(fcntl)
+
--- /dev/null
+.global fif8, Fd0, Fd1, Fd80000000, Fs80000000, Fs0
+
+.align 8
+Fd0:
+.double 0r0
+Fd1:
+.double 0r1
+FxE15:
+.word 0x43300000, 0x0 ! magic const: (a.b + x) - x == a.0
+Fd80000000:
+.align 8
+.double 0r4294967296
+Fs80000000:
+.single 0r2147483648
+Fs0:
+.single 0r0
+
+fif8:
+ ld [%l0], %f0
+ ld [%l0+4], %f1
+ ld [%l0+8], %f2
+ ld [%l0+12], %f3
+ fmuld %f0, %f2, %f0
+ fmovs %f0, %f6
+ fmovs %f1, %f7
+ set Fd0, %o0
+ ldd [%o0], %f8
+ fcmpd %f0, %f8
+ nop
+ fbuge,a 1f
+ mov %g0, %o1
+ set 1, %o1
+ fnegs %f0, %f0
+1:
+ set FxE15, %o0
+ ldd [%o0], %f10
+ fcmpd %f0, %f10
+ nop
+ fbuge 2f
+ nop
+ faddd %f0, %f10, %f4
+ fsubd %f4, %f10, %f4
+ fsubd %f0, %f4, %f2
+ set Fd1, %o0
+ ldd [%o0], %f12
+4: fcmpd %f2, %f12
+ nop
+ fbge,a 4b
+ fsubd %f2, %f12, %f2
+5: fcmpd %f2, %f8
+ nop
+ fbl,a 5b
+ faddd %f2, %f12, %f2
+ fsubd %f0, %f2, %f0
+2:
+ tst %o1
+ bz 3f
+ nop
+ fnegs %f0, %f0
+3:
+ fsubd %f6, %f0, %f2
+ st %f0, [%l0]
+ st %f1, [%l0+4]
+ st %f2, [%l0+8]
+ st %f3, [%l0+12]
+ retl
+ nop
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(flock)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_0(fork)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(fstat)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(fstatfs)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(fsync)
--- /dev/null
+#include <sys/types.h>
+
+ftime(p)
+ struct { time_t time; unsigned short millitm;
+ short timezone; short dstflag; } *p;
+{
+ struct { long l1,l2; } t1,t2;
+
+ if (gettimeofday(&t1,&t2) < 0) return -1;
+ p->time = t1.l1;
+ p->millitm = t1.l2/1000;
+ p->dstflag = t2.l2;
+ p->timezone = t2.l1;
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(ftruncate)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(getdents)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(getdirentries)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(getdomainname)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_0(getdtablesize)
+
--- /dev/null
+#include <syscall.h>
+
+.global _getegid
+_getegid:
+ mov SYS_getgid, %g1
+ ta %g0
+ bgeu 0f
+ sethi %hi(cerror), %o5
+ or %o5, %lo(cerror), %o5
+ jmp %o5
+ nop
+0:
+ mov %o1, %o0
+ retl
+ nop
+
--- /dev/null
+#include <syscall.h>
+
+.global _geteuid
+_geteuid:
+ mov SYS_getuid, %g1
+ ta %g0
+ bgeu 0f
+ sethi %hi(cerror), %o5
+ or %o5, %lo(cerror), %o5
+ jmp %o5
+ nop
+0:
+ mov %o1, %o0
+ retl
+ nop
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_0(getgid)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(getgroups)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(gethostname)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(getitimer)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(getmsg)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(getpeername)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(getpgrp)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_0(getpid)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(getpriority)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(getrlimit)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(getrusage)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(getsockname)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_5(getsockopt)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(gettimeofday)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_0(getuid)
--- /dev/null
+#include <sgtty.h>
+int
+gtty(fildes,argp)
+ int fildes ;
+ struct sgttyb *argp ;
+{
+ return ioctl(fildes,TIOCGETP,argp) ;
+}
--- /dev/null
+.global lino,filn
+.global EXIT
+.global begtext,begdata,begbss
+.global EARRAY,ERANGE,ESET,EIDIVZ,EHEAP,EILLINS,ECASE,EBADGTO
+.global hol0,reghp,limhp,trpim,trppc
+
+! runtime startof for sparc on sun4
+
+
+LINO_AD = 0
+FILN_AD = 4
+
+EARRAY = 0
+ERANGE = 1
+ESET = 2
+EIDIVZ = 6
+EHEAP = 17
+EILLINS = 18
+ECASE = 20
+EBADGTO = 27
+
+ .seg "text"
+
+begtext:
+ clr %fp
+ ld [%sp + 0x40], %o0
+ add %sp, 0x44, %o1
+ sll %o0, 0x2, %o2
+ add %o2, 0x4, %o2
+ add %o1, %o2, %o2
+ set -0x100000, %g4 ! should be a few M
+ clr %l1
+ mov %sp, %l0
+ sub %sp, %g4, %sp
+ dec 12, %l0
+ st %o0, [%l0]
+ st %o1, [%l0+4]
+ st %o2, [%l0+8]
+
+ call __m_a_i_n
+ nop
+ dec 4, %l0
+ st %g0, [%l0]
+EXIT:
+ call __exit
+ nop
+
+ .seg "data"
+begdata:
+ .word 0 ! may be at virtual address 0 with no problem
+hol0:
+lino:
+ .word 0 ! lino
+filn:
+ .word 0 ! filn
+reghp:
+ .word _end
+limhp:
+ .word _end
+trppc:
+ .word 0
+trpim:
+ .word 0 ! USED TO BE 2 BYTES; IS THIS RIGHT?
+
+
+ .seg "bss"
+begbss: !initialization is not needed because ALL entries are in zero space!
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(ioctl)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(kill)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(killpg)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(link)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(listen)
--- /dev/null
+#include <errno.h>
+lockf(fildes, mode, size)
+ long size;
+{
+ struct {
+ short type, whence; long start, end; short pid;
+ } x;
+ int i = 8;
+ extern int errno;
+
+ x.type = 2;
+ x.whence = 1;
+ x.start = 0;
+ x.end = size;
+ switch(mode) {
+ case 0:
+ x.type = 3;
+ break;
+ case 1:
+ i = 9;
+ break;
+ case 2:
+ break;
+ case 3:
+ if (fcntl(fildes,7,&x) == -1) {
+ return -1;
+ }
+ if (x.type == 3) {
+ return 0;
+ }
+ errno = EACCES;
+ return -1;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ if (fcntl(fildes,i,&x) == -1) {
+ if (errno = 79) {
+ errno = 78;
+ }
+ return -1;
+ }
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(lseek)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(lstat)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(mincore)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(mkdir)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(mknod)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_6(mmap)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(mount)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(mprotect)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(msync)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(munmap)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(nfssvc)
--- /dev/null
+nice(incr)
+{
+ extern int errno;
+ int sav = errno;
+ int prio;
+
+ errno = 0;
+ prio = getpriority(0,0);
+ if (prio == -1 && errno) return -1;
+ if (setpriority(0,0,prio+incr) < 0) return -1;
+ errno = sav;
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(open)
--- /dev/null
+pause() {
+ sigpause(sigblock());
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(pipe)
--- /dev/null
+#include <errno.h>
+plock(op)
+{
+ extern int errno;
+
+ errno = EPERM;
+ return -1;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(poll)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(profil)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_5(ptrace)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(putmsg)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(quotactl)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(read)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(readlink)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(readv)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(reboot)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(recv)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_6(recvfrom)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(recvmsg)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(rename)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(rmdir)
--- /dev/null
+.global _sbrk, __sbrk
+
+_sbrk:
+ set __sbrk,%o7
+ jmp %o7
+ nop
--- /dev/null
+#include "SYS.h"
+
+SYS_call_5(select)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(send)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(sendmsg)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_6(sendto)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(setdomainname)
--- /dev/null
+setgid(u)
+{
+ return setregid(u,u);
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(setgroups)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(sethostname)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(setitimer)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(setpgrp)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(setpriority)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(setregid)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(setreuid)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(setrlimit)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_5(setsockopt)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(settimeofday)
--- /dev/null
+setuid(u)
+{
+ return setreuid(u,u);
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(shutdown)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(sigblock)
--- /dev/null
+static long masks[32];
+static long flags[32];
+int (*
+signal(sig,handler))()
+ int (*handler)();
+{
+ struct {
+ int (*sv_handler)();
+ long sv_mask;
+ long sv_flags;
+ } v, ov;
+
+ v.sv_handler = handler;
+ v.sv_mask = masks[sig];
+ v.sv_flags = flags[sig];
+ if (sigvec(sig,&v, &ov) < 0) return (int (*)()) -1;
+ if (v.sv_mask != ov.sv_mask || v.sv_flags != ov.sv_flags) {
+ v.sv_mask = ov.sv_mask;
+ masks[sig] = ov.sv_mask;
+ v.sv_flags = ov.sv_flags;
+ flags[sig] = ov.sv_flags;
+ if (sigvec(sig,&v,(char *) 0) < 0) return (int (*)()) -1;
+ }
+ return ov.sv_handler;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(sigpause)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(sigsetmask)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(sigstack)
--- /dev/null
+.global __sigtramp
+
+__sigtramp:
+ dec 0x10, %sp
+ st %g1, [%sp+0x44]
+ std %l0, [%sp+0x48]
+ save %sp, %g4, %sp
+ st %g0, [%sp + 64]
+ clr %l1
+ mov %fp, %l0
+
+ ld [%fp + 0x58], %o2
+ set 0x1000, %l3
+ ld [%o2 + 0x14], %o0
+ rd %y, %l4
+ andcc %o0, %l3, %g0
+ be 1f
+ st %l4, [%sp + 0xe4]
+ std %f0, [%sp + 0x60]
+ std %f2, [%sp + 0x68]
+ std %f4, [%sp + 0x70]
+ std %f6, [%sp + 0x78]
+ std %f8, [%sp + 0x80]
+ std %f10, [%sp + 0x88]
+ std %f12, [%sp + 0x90]
+ std %f14, [%sp + 0x98]
+ std %f16, [%sp + 0xa0]
+ std %f18, [%sp + 0xa8]
+ std %f20, [%sp + 0xb0]
+ std %f22, [%sp + 0xb8]
+ std %f24, [%sp + 0xc0]
+ std %f26, [%sp + 0xc8]
+ std %f28, [%sp + 0xd0]
+ std %f30, [%sp + 0xd8]
+ st %fsr, [%sp + 0xe0]
+1:
+ std %g2, [%sp + 0xe8]
+ std %g4, [%sp + 0xf0]
+ std %g6, [%sp + 0xf8]
+
+ ld [%fp + 0x50], %o0
+ dec 4, %l0
+ st %o0, [%l0]
+ set __sigfunc, %g1
+ sll %o0, 2, %g2
+ add %g1, %g2, %g3
+ ld [%g3], %g2
+
+ call %g2
+ nop
+ ld [%fp + 0x5c], %o3
+ ld [%fp + 0x58], %i0
+ ld [%sp + 0xe4], %l1
+ ld [%i0 + 0x14], %o0
+ mov %l1, %y
+ andcc %o0, %l3, %g0
+ be 2f
+ ldd [%sp + 0xe8], %g2
+ ldd [%sp + 0x60], %f0
+ ldd [%sp + 0x68], %f2
+ ldd [%sp + 0x70], %f4
+ ldd [%sp + 0x78], %f6
+ ldd [%sp + 0x80], %f8
+ ldd [%sp + 0x88], %f10
+ ldd [%sp + 0x90], %f12
+ ldd [%sp + 0x98], %f14
+ ldd [%sp + 0xa0], %f16
+ ldd [%sp + 0xa8], %f18
+ ldd [%sp + 0xb0], %f20
+ ldd [%sp + 0xb8], %f22
+ ldd [%sp + 0xc0], %f24
+ ldd [%sp + 0xc8], %f26
+ ldd [%sp + 0xd0], %f28
+ ldd [%sp + 0xd8], %f30
+ ld [%sp + 0xe0], %fsr
+2:
+ ldd [%sp + 0xf0], %g4
+ ldd [%sp + 0xf8], %g6
+
+ restore %g0, 0x8b, %g1
+
+ ldd [%sp+0x48], %l0
+ inc 0x10, %sp
+ ta %g0
+ nop
--- /dev/null
+#include "syscall.h"
+#include <errno.h>
+struct sigvec { int (*handler)(); int mask,flags; };
+int (*(_sigfunc[32]))();
+extern int _sigtramp();
+extern int errno;
+
+sigvec(sig,vec,ovec)
+ register struct sigvec *vec;
+ struct sigvec *ovec;
+{
+ struct sigvec tmp;
+ int (*old)();
+
+ if ((unsigned) sig >= 32) {
+ errno = EINVAL;
+ return -1;
+ }
+ old = _sigfunc[sig];
+ if (vec) {
+ tmp = *vec;
+ vec = &tmp;
+ if (vec->handler && vec->handler != (int (*)()) 1) {
+ _sigfunc[sig] = vec->handler;
+ vec->handler = _sigtramp;
+ }
+ }
+ if (sigvec_scall(sig,vec,ovec) < 0) {
+ _sigfunc[sig] = old;
+ return -1;
+ }
+ if (ovec && ovec->handler == _sigtramp) {
+ ovec->handler = old;
+ }
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+#define SYS_sigvec_scall SYS_sigvec
+
+SYS_call_3(sigvec_scall)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(socket)
+
--- /dev/null
+#include "SYS.h"
+
+SYS_call_4(socketpair)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(stat)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(statfs)
--- /dev/null
+stime(tp)
+ long *tp;
+{
+ struct { long l1,l2; } x;
+
+ x.l1 = *tp;
+ x.l2 = 0;
+ return settimeofday(&x, (char *) 0);
+}
--- /dev/null
+#include <sgtty.h>
+int stty(fildes,argp)
+ int fildes ;
+ struct sgttyb *argp ;
+{
+ return ioctl(fildes,TIOCSETP,argp) ;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(swapon)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(symlink)
--- /dev/null
+/* $Header$ */
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define SYS_exit 1
+#define SYS_fork 2
+#define SYS_read 3
+#define SYS_write 4
+#define SYS_open 5
+#define SYS_close 6
+#define SYS_creat 8
+#define SYS_link 9
+#define SYS_unlink 10
+#define SYS_execv 11
+#define SYS_chdir 12
+#define SYS_mknod 14
+#define SYS_chmod 15
+#define SYS_chown 16
+#define SYS_lseek 19
+#define SYS_getpid 20
+#define SYS_getuid 24
+#define SYS_ptrace 26
+#define SYS_access 33
+#define SYS_sync 36
+#define SYS_kill 37
+#define SYS_stat 38
+#define SYS_lstat 40
+#define SYS_dup 41
+#define SYS_pipe 42
+#define SYS_profil 44
+#define SYS_getgid 47
+#define SYS_acct 51
+#define SYS_ioctl 54
+#define SYS_reboot 55
+#define SYS_symlink 57
+#define SYS_readlink 58
+#define SYS_execve 59
+#define SYS_umask 60
+#define SYS_chroot 61
+#define SYS_fstat 62
+#define SYS_getpagesize 64
+#define SYS_mremap 65
+#define SYS_vfork 66
+#define SYS_sbrk 69
+#define SYS_sstk 70
+#define SYS_mmap 71
+#define SYS_vadvise 72
+#define SYS_munmap 73
+#define SYS_mprotect 74
+#define SYS_madvise 75
+#define SYS_vhangup 76
+#define SYS_mincore 78
+#define SYS_getgroups 79
+#define SYS_setgroups 80
+#define SYS_getpgrp 81
+#define SYS_setpgrp 82
+#define SYS_setitimer 83
+#define SYS_wait 84
+#define SYS_swapon 85
+#define SYS_getitimer 86
+#define SYS_gethostname 87
+#define SYS_sethostname 88
+#define SYS_getdtablesize 89
+#define SYS_dup2 90
+#define SYS_getdopt 91
+#define SYS_fcntl 92
+#define SYS_select 93
+#define SYS_setdopt 94
+#define SYS_fsync 95
+#define SYS_setpriority 96
+#define SYS_socket 97
+#define SYS_connect 98
+#define SYS_accept 99
+#define SYS_getpriority 100
+#define SYS_send 101
+#define SYS_recv 102
+#define SYS_bind 104
+#define SYS_setsockopt 105
+#define SYS_listen 106
+#define SYS_sigvec 108
+#define SYS_sigblock 109
+#define SYS_sigsetmask 110
+#define SYS_sigpause 111
+#define SYS_sigstack 112
+#define SYS_recvmsg 113
+#define SYS_sendmsg 114
+#define SYS_gettimeofday 116
+#define SYS_getrusage 117
+#define SYS_getsockopt 118
+#define SYS_readv 120
+#define SYS_writev 121
+#define SYS_settimeofday 122
+#define SYS_fchown 123
+#define SYS_fchmod 124
+#define SYS_recvfrom 125
+#define SYS_setreuid 126
+#define SYS_setregid 127
+#define SYS_rename 128
+#define SYS_truncate 129
+#define SYS_ftruncate 130
+#define SYS_flock 131
+#define SYS_sendto 133
+#define SYS_shutdown 134
+#define SYS_socketpair 135
+#define SYS_mkdir 136
+#define SYS_rmdir 137
+#define SYS_utimes 138
+#define SYS_adjtime 140
+#define SYS_getpeername 141
+#define SYS_gethostid 142
+#define SYS_getrlimit 144
+#define SYS_setrlimit 145
+#define SYS_killpg 146
+#define SYS_getsockname 150
+#define SYS_nfssvc 155
+#define SYS_getdirentries 156
+#define SYS_statfs 157
+#define SYS_fstatfs 158
+#define SYS_umount 159
+#define SYS_async_daemon 160
+#define SYS_getfh 161
+#define SYS_getdomainname 162
+#define SYS_setdomainname 163
+#define SYS_quotactl 165
+#define SYS_exportfs 166
+#define SYS_mount 167
+#define SYS_ustat 168
+#define SYS_semsys 169
+#define SYS_msgsys 170
+#define SYS_shmsys 171
--- /dev/null
+long
+tell(f)
+{
+ long lseek();
+
+ return lseek(f, 0L, 1);
+}
--- /dev/null
+long
+time(loc)
+ long *loc;
+{
+ struct { long l1,l2; } t1;
+
+ if (gettimeofday(&t1, (char *) 0) < 0) {
+ return -1;
+ }
+ if (loc) *loc = t1.l1;
+ return t1.l1;
+}
--- /dev/null
+#include <sys/types.h>
+
+#define Xval(xx) ((xx).l1*60+(xx).l2/(100000/6))
+
+times(bp)
+ struct { time_t l1,l2,l3,l4;} *bp;
+{
+ struct { struct { long l1,l2; }s1,s2; long x[20]; } t;
+ if (getrusage(0,&t) < 0) return -1;
+ bp->l1 = Xval(t.s1);
+ bp->l2 = Xval(t.s2);
+ if (getrusage(-1,&t) < 0) return -1;
+ bp->l3 = Xval(t.s1);
+ bp->l4 = Xval(t.s2);
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(truncate)
--- /dev/null
+#include <errno.h>
+
+ulimit(cmd, newlimit)
+ long newlimit;
+{
+ extern int errno;
+ struct {
+ long soft, hard;
+ } x;
+
+ switch(cmd) {
+ case 1:
+ if (getrlimit(1, &x) < 0) return -1;
+ return ((x.soft + 511) & ~511) >> 9;
+ case 2:
+ x.soft = x.hard = (newlimit << 9);
+ if (setrlimit(1, &x) < 0) return -1;
+ return x.soft;
+ case 3:
+ if (getrlimit(2, &x) < 0) return -1;
+ return x.soft;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(umask)
--- /dev/null
+extern int errno;
+
+struct utsname {
+ char sysname[9],nodename[9],release[9],version[9],machine[9];
+};
+
+static char def_node[] = "unknown";
+static char rel[] = "4.2BSD";
+static char ver[] = "vm";
+static char mach[] = "sun";
+
+uname(nm)
+ register struct utsname *nm;
+{
+ register char *p = nm->nodename;
+
+ while (p <= nm->release) *p++ = 0;
+ if (gethostname(nm->nodename,9) == -1) {
+ strcpy(nm->nodename, def_node);
+ }
+ strncpy(nm->sysname,nm->nodename,9);
+ strncpy(nm->release,rel,9);
+ strncpy(nm->version,ver,9);
+ strncpy(nm->machine,mach,9);
+ return 0;
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(unlink)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(unmount)
--- /dev/null
+#include <sys/types.h>
+
+utime(file, timep)
+ char *file;
+ time_t timep[2];
+{
+ struct { long l1,l2,l3,l4; } x;
+
+ x.l2 = x.l4 = 0;
+ x.l1 = timep[0];
+ x.l3 = timep[1];
+ return utimes(file,&x);
+}
--- /dev/null
+#include "SYS.h"
+
+SYS_call_2(utimes)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_1(vadvise)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_0(vfork)
--- /dev/null
+#include "SYS.h"
+
+.global _wait, _wait3
+
+_wait:
+ mov 0, %o0
+ ld [%l0], %o1
+ mov 0, %o2
+ b wait4
+ mov 0, %o3
+
+_wait3:
+ ld [%l0+8], %o3
+ ld [%l0+4], %o2
+ ld [%l0], %o1
+ b wait4
+ mov 0, %o0
+
+SYS_call_4(wait4)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(write)
--- /dev/null
+#include "SYS.h"
+
+SYS_call_3(writev)