summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgcode.c22
-rw-r--r--cgias.c697
-rw-r--r--cgiconst.h7
-rw-r--r--cginstructions.c46
-rw-r--r--cgiwas.c852
-rw-r--r--cglin.c418
-rw-r--r--cgopt.c99
-rw-r--r--cgrconst.h4
-rw-r--r--cgstack.c94
9 files changed, 2053 insertions, 186 deletions
diff --git a/cgcode.c b/cgcode.c
index 49b169f..2b2a6d5 100644
--- a/cgcode.c
+++ b/cgcode.c
@@ -353,7 +353,10 @@ LABEL *collect_0_label,*collect_1_label,*collect_2_label,
*eval_01_label,*eval_11_label,*eval_02_label,*eval_12_label,*eval_22_label,
#endif
#if defined (I486) && defined (GEN_OBJ) && !defined (G_AI64)
- *collect_0l_label,*collect_1l_label,*collect_2l_label,*end_heap_label,
+ *collect_0l_label,*collect_1l_label,*collect_2l_label,
+# ifndef THREAD32
+ *end_heap_label,
+# endif
#endif
*system_sp_label,*EMPTY_label;
@@ -699,7 +702,7 @@ void code_and (VOID)
graph_1=s_pop_b();
graph_2=s_get_b (0);
graph_3=g_and (graph_1,graph_2);
-
+
s_put_b (0,graph_3);
}
@@ -3963,7 +3966,7 @@ void code_jmp (char label_name[])
if (mc68881_flag){
int parameter_n;
-
+
for (parameter_n=0; parameter_n<b_stack_size; ++parameter_n)
if (test_bit (vector,parameter_n))
if (n_a_and_f_registers<N_FLOAT_PARAMETER_REGISTERS){
@@ -4221,8 +4224,15 @@ void code_jmp_eval_upd (VOID)
# else
i_move_r_id (REGISTER_D0,0,REGISTER_A0);
# ifdef I486
+# ifndef THREAD32
i_move_id_id (STACK_ELEMENT_SIZE,REGISTER_A1,STACK_ELEMENT_SIZE,REGISTER_A0);
i_move_id_id (2*STACK_ELEMENT_SIZE,REGISTER_A1,2*STACK_ELEMENT_SIZE,REGISTER_A0);
+# else
+ i_move_id_r (STACK_ELEMENT_SIZE,REGISTER_A1,REGISTER_A2);
+ i_move_r_id (REGISTER_A2,STACK_ELEMENT_SIZE,REGISTER_A0);
+ i_move_id_r (2*STACK_ELEMENT_SIZE,REGISTER_A1,REGISTER_A2);
+ i_move_r_id (REGISTER_A2,2*STACK_ELEMENT_SIZE,REGISTER_A0);
+# endif
# else
i_move_id_r (STACK_ELEMENT_SIZE,REGISTER_A1,REGISTER_D1);
i_move_id_r (2*STACK_ELEMENT_SIZE,REGISTER_A1,REGISTER_D2);
@@ -7506,7 +7516,7 @@ static void code_selectR (VOID)
g_fhighlow (graph_5,graph_6,graph_4);
#endif
}
-
+
#ifndef G_A64
s_push_b (graph_6);
#endif
@@ -9252,7 +9262,6 @@ void code_record (char record_label_name[],char type[],int a_size,int b_size,cha
#ifdef GEN_OBJ
store_2_words_in_data_section (a_size+b_size+256,a_size);
#endif
-
if (assembly_flag){
w_as_word_in_data_section (a_size+b_size+256);
w_as_word_in_data_section (a_size);
@@ -9616,7 +9625,6 @@ static LABEL *code_string_or_module (char label_name[],char string[],int string_
define_data_label (label);
store_abc_string_in_data_section (string,string_length);
#endif
-
if (assembly_flag)
w_as_abc_string_and_label_in_data_section (string,string_length,label_name);
@@ -9985,7 +9993,9 @@ void initialize_coding (VOID)
collect_0l_label=enter_label ("collect_0l",IMPORT_LABEL);
collect_1l_label=enter_label ("collect_1l",IMPORT_LABEL);
collect_2l_label=enter_label ("collect_2l",IMPORT_LABEL);
+# ifndef THREAD32
end_heap_label=enter_label ("end_heap",IMPORT_LABEL);
+# endif
#endif
#ifdef G_POWER
collect_00_label=enter_label ("collect_00",IMPORT_LABEL);
diff --git a/cgias.c b/cgias.c
index e58b132..1985533 100644
--- a/cgias.c
+++ b/cgias.c
@@ -869,7 +869,7 @@ static void as_id_r (int code,int offset,int reg1,int reg2)
#define as_r_x(code,reg3,offset,index_registers) as_x_r(code,offset,index_registers,reg3)
static void as_x_r (int code,int offset,struct index_registers *index_registers,int reg3)
-{
+{
int reg1,reg2,shift;
reg1=index_registers->a_reg.r;
@@ -2127,6 +2127,9 @@ struct ms magic (int d)
static void as_div_rem_i_instruction (struct instruction *instruction,int compute_remainder)
{
int s_reg1,s_reg2,s_reg3,i,sd_reg,i_reg,tmp_reg,abs_i;
+#ifdef THREAD32
+ int tmp2_reg;
+#endif
struct ms ms;
if (instruction->instruction_parameters[0].parameter_type!=P_IMMEDIATE)
@@ -2147,6 +2150,7 @@ static void as_div_rem_i_instruction (struct instruction *instruction,int comput
sd_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
tmp_reg=instruction->instruction_parameters[2].parameter_data.reg.r;
+#ifndef THREAD32
if (sd_reg==tmp_reg)
internal_error_in_function ("as_div_rem_i_instruction");
@@ -2180,6 +2184,57 @@ static void as_div_rem_i_instruction (struct instruction *instruction,int comput
s_reg2=sd_reg;
i_reg=REGISTER_D0;
}
+#else
+ tmp2_reg=instruction->instruction_parameters[3].parameter_data.reg.r;
+
+ if (sd_reg==tmp_reg || sd_reg==tmp2_reg)
+ internal_error_in_function ("as_div_rem_i_instruction");
+
+ if (sd_reg==REGISTER_A1){
+ if (tmp2_reg==REGISTER_D0){
+ s_reg2=tmp_reg;
+ } else {
+ if (tmp_reg!=REGISTER_D0)
+ as_move_r_r (REGISTER_D0,tmp_reg);
+ s_reg2=tmp2_reg;
+ }
+ as_move_r_r (REGISTER_A1,s_reg2);
+ s_reg1=REGISTER_A1;
+ i_reg=REGISTER_D0;
+ } else if (sd_reg==REGISTER_D0){
+ if (tmp2_reg==REGISTER_A1){
+ s_reg2=tmp_reg;
+ } else {
+ if (tmp_reg!=REGISTER_A1)
+ as_move_r_r (REGISTER_A1,tmp_reg);
+ s_reg2=tmp2_reg;
+ }
+ as_move_r_r (REGISTER_D0,s_reg2);
+ s_reg1=REGISTER_A1;
+ i_reg=REGISTER_A1;
+ } else {
+ if (tmp_reg==REGISTER_D0){
+ if (tmp2_reg!=REGISTER_A1)
+ as_move_r_r (REGISTER_A1,tmp2_reg);
+ } else if (tmp_reg==REGISTER_A1){
+ if (tmp2_reg!=REGISTER_D0)
+ as_move_r_r (REGISTER_D0,tmp2_reg);
+ } else {
+ if (tmp2_reg==REGISTER_D0){
+ as_move_r_r (REGISTER_A1,tmp_reg);
+ } else if (tmp2_reg==REGISTER_A1){
+ as_move_r_r (REGISTER_D0,tmp_reg);
+ } else {
+ as_move_r_r (REGISTER_D0,tmp2_reg);
+ as_move_r_r (REGISTER_A1,tmp_reg);
+ }
+ }
+
+ s_reg1=sd_reg;
+ s_reg2=sd_reg;
+ i_reg=REGISTER_D0;
+ }
+#endif
as_move_i_r (ms.m,i_reg);
@@ -2285,6 +2340,7 @@ static void as_div_rem_i_instruction (struct instruction *instruction,int comput
as_move_r_r (s_reg3,sd_reg);
}
+#ifndef THREAD32
if (sd_reg==REGISTER_A1){
if (tmp_reg!=REGISTER_D0)
as_move_r_r (tmp_reg,REGISTER_D0);
@@ -2301,8 +2357,35 @@ static void as_div_rem_i_instruction (struct instruction *instruction,int comput
as_move_r_r (tmp_reg,REGISTER_A1);
}
}
+#else
+ if (sd_reg==REGISTER_A1){
+ if (tmp2_reg!=REGISTER_D0 && tmp_reg!=REGISTER_D0)
+ as_move_r_r (tmp_reg,REGISTER_D0);
+ } else if (sd_reg==REGISTER_D0){
+ if (tmp2_reg!=REGISTER_A1 && tmp_reg!=REGISTER_A1)
+ as_move_r_r (tmp_reg,REGISTER_A1);
+ } else {
+ if (tmp_reg==REGISTER_D0){
+ if (tmp2_reg!=REGISTER_A1)
+ as_move_r_r (tmp2_reg,REGISTER_A1);
+ } else if (tmp_reg==REGISTER_A1){
+ if (tmp2_reg!=REGISTER_D0)
+ as_move_r_r (tmp2_reg,REGISTER_D0);
+ } else {
+ if (tmp2_reg==REGISTER_D0){
+ as_move_r_r (tmp_reg,REGISTER_A1);
+ } else if (tmp2_reg==REGISTER_A1){
+ as_move_r_r (tmp_reg,REGISTER_D0);
+ } else {
+ as_move_r_r (tmp2_reg,REGISTER_D0);
+ as_move_r_r (tmp_reg,REGISTER_A1);
+ }
+ }
+ }
+#endif
}
+#ifndef THREAD32
static void as_div_instruction (struct instruction *instruction,int unsigned_div)
{
int d_reg,opcode2;
@@ -2454,7 +2537,273 @@ static void as_div_instruction (struct instruction *instruction,int unsigned_div
as_move_r_r (REGISTER_O0,REGISTER_A1);
}
}
+#else
+static void as_div_instruction (struct instruction *instruction,int unsigned_div)
+{
+ int d_reg,tmp_reg,opcode2;
+
+ d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
+ tmp_reg=instruction->instruction_parameters[2].parameter_data.reg.r;
+
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_div==0){
+ int i,log2i;
+
+ i=instruction->instruction_parameters[0].parameter_data.i;
+
+ if (! ((i & (i-1))==0 && i>0)){
+ internal_error_in_function ("as_div_instruction");
+ return;
+ }
+
+ if (i==1)
+ return;
+
+ log2i=0;
+ while (i>1){
+ i=i>>1;
+ ++log2i;
+ }
+
+ as_move_r_r (d_reg,tmp_reg);
+
+ if (log2i==1){
+ as_sar_i_r (31,tmp_reg);
+
+ as_r_r (0053,tmp_reg,d_reg); /* sub */
+ } else {
+ as_sar_i_r (31,d_reg);
+
+ /* and */
+ if (d_reg==EAX)
+ store_c (045);
+ else
+ as_r (0201,040,d_reg);
+ store_l ((1<<log2i)-1);
+ as_r_r (0003,tmp_reg,d_reg); /* add */
+ }
+
+ as_sar_i_r (log2i,d_reg);
+
+ return;
+ }
+
+ opcode2=unsigned_div ? 0060 : 0070;
+
+ switch (d_reg){
+ case REGISTER_D0:
+ if (tmp_reg==REGISTER_A1){
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+ } else {
+ as_move_r_r (REGISTER_A1,tmp_reg);
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ as_r (0367,opcode2,tmp_reg);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,tmp_reg);
+ } else
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (tmp_reg,REGISTER_A1);
+ }
+ break;
+ case REGISTER_A1:
+ if (tmp_reg==REGISTER_D0){
+ as_move_r_r (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (00367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (REGISTER_D0,REGISTER_A1);
+ } else {
+ as_move_r_r (REGISTER_D0,tmp_reg);
+ as_move_r_r (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (00367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (REGISTER_D0,REGISTER_A1);
+ as_move_r_r (tmp_reg,REGISTER_D0);
+ }
+ break;
+ default:
+ if (tmp_reg==REGISTER_D0){
+ as_move_r_r (d_reg,REGISTER_D0);
+ as_move_r_r (REGISTER_A1,d_reg);
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (d_reg,REGISTER_A1);
+ as_move_r_r (REGISTER_D0,d_reg);
+ } else if (tmp_reg==REGISTER_A1){
+ store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+
+ store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
+ } else {
+ as_move_r_r (REGISTER_A1,tmp_reg);
+ store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+
+ store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
+ as_move_r_r (tmp_reg,REGISTER_A1);
+ }
+ }
+}
+#endif
+
+#ifndef THREAD32
static void as_rem_instruction (struct instruction *instruction,int unsigned_rem)
{
int d_reg,opcode2;
@@ -2620,6 +2969,283 @@ static void as_rem_instruction (struct instruction *instruction,int unsigned_rem
as_move_r_r (REGISTER_O0,REGISTER_A1);
}
}
+#else
+static void as_rem_instruction (struct instruction *instruction,int unsigned_rem)
+{
+ int d_reg,tmp_reg,opcode2;
+
+ d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
+ tmp_reg=instruction->instruction_parameters[2].parameter_data.reg.r;
+
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){
+ int i,log2i;
+
+ i=instruction->instruction_parameters[0].parameter_data.i;
+
+ if (i<0 && i!=0x80000000)
+ i=-i;
+
+ if (! ((i & (i-1))==0 && i>1)){
+ internal_error_in_function ("as_rem_instruction");
+ return;
+ }
+
+ log2i=0;
+ while (i>1){
+ i=i>>1;
+ ++log2i;
+ }
+
+ as_move_r_r (d_reg,tmp_reg);
+
+ if (log2i==1){
+ /* and */
+ if (d_reg==EAX)
+ store_c (045);
+ else
+ as_r (0201,040,d_reg);
+ store_l (1);
+
+ as_sar_i_r (31,tmp_reg);
+
+ as_r_r (0063,tmp_reg,d_reg); /* xor */
+ } else {
+ as_sar_i_r (31,tmp_reg);
+
+ /* and */
+ if (tmp_reg==EAX)
+ store_c (045);
+ else
+ as_r (0201,040,tmp_reg);
+ store_l ((1<<log2i)-1);
+
+ as_r_r (0003,tmp_reg,d_reg); /* add */
+
+ /* and */
+ if (d_reg==EAX)
+ store_c (045);
+ else
+ as_r (0201,040,d_reg);
+ store_l ((1<<log2i)-1);
+ }
+
+ as_r_r (0053,tmp_reg,d_reg); /* sub */
+
+ return;
+ }
+
+ opcode2=unsigned_rem ? 0060 : 0070;
+
+ switch (d_reg){
+ case REGISTER_D0:
+ if (tmp_reg==REGISTER_A1){
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (REGISTER_A1,REGISTER_D0);
+ } else {
+ as_move_r_r (REGISTER_A1,tmp_reg);
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ as_r (0367,opcode2,tmp_reg);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,tmp_reg);
+ } else
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (REGISTER_A1,REGISTER_D0);
+ as_move_r_r (tmp_reg,REGISTER_A1);
+ }
+ break;
+ case REGISTER_A1:
+ if (tmp_reg==REGISTER_D0){
+ as_move_r_r (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+ } else {
+ as_move_r_r (REGISTER_D0,tmp_reg);
+ as_move_r_r (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (tmp_reg,REGISTER_D0);
+ }
+ break;
+ default:
+ if (tmp_reg==REGISTER_D0){
+ as_move_r_r (d_reg,REGISTER_D0);
+ as_move_r_r (REGISTER_A1,d_reg);
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_r_r (0207,d_reg,REGISTER_A1); /* xchg */
+ } else if (tmp_reg==REGISTER_A1){
+ store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (d_reg,REGISTER_D0);
+ as_move_r_r (REGISTER_A1,d_reg);
+ } else {
+ as_move_r_r (REGISTER_A1,tmp_reg);
+ store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+ /* idivl */
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_r (0367,opcode2,r);
+ } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
+
+ as_move_r_r (d_reg,REGISTER_D0);
+ as_move_r_r (REGISTER_A1,d_reg);
+ as_move_r_r (tmp_reg,REGISTER_A1);
+ }
+ }
+}
+#endif
static void as_2move_registers (int reg1,int reg2,int reg3)
{
@@ -2634,6 +3260,7 @@ static void as_3move_registers (int reg1,int reg2,int reg3,int reg4)
as_move_r_r (reg1,reg2);
}
+#ifndef THREAD32
static void as_mulud_instruction (struct instruction *instruction)
{
int reg_1,reg_2;
@@ -2711,12 +3338,14 @@ static void as_mulud_instruction (struct instruction *instruction)
as_2move_registers (REGISTER_O0,REGISTER_A1,reg_1);
}
}
+#endif
static void as_xchg_eax_r (int reg_1)
{
store_c (0x90+reg_num (reg_1)); /* xchg reg_1,D0 */
}
+#ifndef THREAD32
static void as_divdu_instruction (struct instruction *instruction)
{
int reg_1,reg_2,reg_3;
@@ -2833,6 +3462,7 @@ static void as_divdu_instruction (struct instruction *instruction)
}
}
}
+#endif
static void as_mul_shift_magic (int s)
{
@@ -3330,6 +3960,27 @@ static void as_rtsi_instruction (struct instruction *instruction)
store_w (instruction->instruction_parameters[0].parameter_data.i);
}
+#ifdef THREAD32
+static void as_ldtsp_instruction (struct instruction *instruction)
+{
+ int reg,reg_n;
+
+ reg=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ /* mov label,reg */
+ as_r_a (0213,reg,instruction->instruction_parameters[0].parameter_data.l);
+
+ reg_n=reg_num (reg);
+
+ /* mov fs:[0x0e10+reg*4],reg */
+ store_c (0x64); /* fs prefix */
+ store_c (0213);
+ store_c (4 | (reg_n<<3));
+ store_c (0205 | (reg_n<<3));
+ store_l (0x0e10);
+}
+#endif
+
static void as_f_r (int code1,int code2,int freg)
{
store_c (code1);
@@ -4589,8 +5240,9 @@ static void as_fmovel_instruction (struct instruction *instruction)
{
if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){
- LABEL *new_label;
int s_freg;
+#ifndef THREAD32
+ LABEL *new_label;
new_label=allocate_memory_from_heap (sizeof (struct label));
@@ -4606,12 +5258,22 @@ static void as_fmovel_instruction (struct instruction *instruction)
} else
as_f_a (0xdb,2,new_label); /* fist */
as_r_a (0x8b,instruction->instruction_parameters[1].parameter_data.reg.r,new_label);
+#else
+ s_freg=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (s_freg!=0){
+ as_f_r (0xd9,0xc0,s_freg); /* fld s_freg */
+ as_f_id (0xdb,8,REGISTER_A4,3); /* fistp */
+ } else
+ as_f_id (0xdb,8,REGISTER_A4,2); /* fist */
+ as_id_r (0213,8,REGISTER_A4,instruction->instruction_parameters[1].parameter_data.reg.r); /* mov */
+#endif
} else
internal_error_in_function ("as_fmovel_instruction");
} else {
switch (instruction->instruction_parameters[0].parameter_type){
case P_REGISTER:
{
+#ifndef THREAD32
LABEL *new_label;
new_label=allocate_memory_from_heap (sizeof (struct label));
@@ -4623,6 +5285,10 @@ static void as_fmovel_instruction (struct instruction *instruction)
as_r_a (0211,instruction->instruction_parameters[0].parameter_data.reg.r,new_label);
as_f_a (0xdb,0,new_label); /* fildl */
+#else
+ as_r_id (0211,instruction->instruction_parameters[0].parameter_data.reg.r,8,REGISTER_A4); /* mov */
+ as_f_id (0xdb,8,REGISTER_A4,0); /* fildl */
+#endif
break;
}
case P_INDIRECT:
@@ -4893,12 +5559,14 @@ static void as_instructions (struct instruction *instruction)
case ISBB:
as_sbb_instruction (instruction);
break;
+#ifndef THREAD32
case IMULUD:
as_mulud_instruction (instruction);
break;
case IDIVDU:
as_divdu_instruction (instruction);
break;
+#endif
case IFLOORDIV:
as_floordiv_mod_instruction (instruction,0);
break;
@@ -5039,6 +5707,11 @@ static void as_instructions (struct instruction *instruction)
case IFSINCOS:
as_fsincos_instruction (instruction);
break;
+#ifdef THREAD32
+ case ILDTLSP:
+ as_ldtsp_instruction (instruction);
+ break;
+#endif
default:
internal_error_in_function ("as_instructions");
}
@@ -5086,11 +5759,24 @@ static void as_garbage_collect_test (struct basic_block *block)
first_call_and_jump=new_call_and_jump;
last_call_and_jump=new_call_and_jump;
+#ifdef THREAD32
+ as_id_r (0213,0,REGISTER_A4,HEAP_POINTER); /* mov */
+#endif
+
if (n_cells<=8)
+#ifndef THREAD32
as_r_a (0073,HEAP_POINTER,end_heap_label); /* cmp */
+#else
+ as_id_r (0073,4,REGISTER_A4,HEAP_POINTER); /* cmp */
+#endif
else {
+#ifndef THREAD32
as_id_r (0215,(n_cells-8)<<2,HEAP_POINTER,REGISTER_O0); /* lea */
as_r_a (0073,REGISTER_O0,end_heap_label); /* cmp */
+#else
+ as_i_r2 (0201,0000,0005,(n_cells-8)<<2,HEAP_POINTER); /* add */
+ as_id_r (0073,4,REGISTER_A4,HEAP_POINTER); /* cmp */
+#endif
}
store_c (0x0f);
@@ -5104,6 +5790,11 @@ static void as_garbage_collect_test (struct basic_block *block)
new_call_and_jump->cj_jump.label_object_label=code_object_label;
#endif
new_call_and_jump->cj_jump.label_offset=CURRENT_CODE_OFFSET;
+
+#ifdef THREAD32
+ if (n_cells>8)
+ as_id_r (0213,0,REGISTER_A4,HEAP_POINTER); /* mov */
+#endif
}
static void as_call_and_jump (struct call_and_jump *call_and_jump)
@@ -5947,7 +6638,7 @@ static void write_file_header_and_section_headers (void)
write_l (data_section_length);
write_l (0);
write_l (0);
- write_l (object_label->object_section_align8 ? 8 : 4);
+ write_l (object_label->object_section_align8 ? 8 : 4);
write_l (0);
section_string_offset+=8+n_digits (object_label->object_label_section_n);
diff --git a/cgiconst.h b/cgiconst.h
index cc166bc..0370853 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -68,7 +68,10 @@ enum {
#endif
#if defined (I486)
,IADC ,ISBB, IRTSI
- ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD, IDIVDU
+ ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD
+# ifndef THREAD32
+ ,IMULUD, IDIVDU
+# endif
,IFLOADS, IFMOVES
#endif
#if defined (I486) || defined (G_POWER)
@@ -80,7 +83,7 @@ enum {
#ifdef G_AI64
,ILOADSQB, IMOVEQB, IFCVT2S
#endif
-#if defined (THREAD64)
+#if defined (THREAD32) || defined (THREAD64)
,ILDTLSP
#endif
};
diff --git a/cginstructions.c b/cginstructions.c
index 3aaa899..0a80512 100644
--- a/cginstructions.c
+++ b/cginstructions.c
@@ -37,7 +37,7 @@
# endif
# endif
#endif
-#if defined (THREAD64)
+#if defined (THREAD32) || defined (THREAD64)
# include "cgiconst.h"
#endif
#ifndef MACH_O64
@@ -64,7 +64,7 @@ LABEL *saved_heap_p_label,*saved_a_stack_p_label;
#ifdef MACH_O
LABEL *dyld_stub_binding_helper_p_label;
#endif
-#if defined (THREAD64)
+#if defined (THREAD32) || defined (THREAD64)
LABEL *tlsp_tls_index_label;
#endif
@@ -3650,10 +3650,14 @@ static void ccall_load_string_or_array_offset (int offset,int c_parameter_n,int
}
#endif
-#ifdef THREAD64
-# define SAVED_HEAP_P_OFFSET 24
-# define SAVED_R15_OFFSET 32
-# define SAVED_A_STACK_P_OFFSET 40
+#ifdef THREAD32
+# define SAVED_A_STACK_P_OFFSET 12
+#else
+# ifdef THREAD64
+# define SAVED_HEAP_P_OFFSET 24
+# define SAVED_R15_OFFSET 32
+# define SAVED_A_STACK_P_OFFSET 40
+# endif
#endif
void code_ccall (char *c_function_name,char *s,int length)
@@ -4186,12 +4190,12 @@ void code_ccall (char *c_function_name,char *s,int length)
break;
default:
error_s (ccall_error_string,c_function_name);
- }
+ }
#elif defined (I486)
# ifndef G_AI64 /* for I486 && ! G_AI64 */
- {
+ {
int c_offset_before_pushing_arguments,function_address_reg;
int b_out_and_ab_result_size;
@@ -4436,8 +4440,12 @@ void code_ccall (char *c_function_name,char *s,int length)
}
if (save_state_in_global_variables){
+# ifndef THREAD32
i_move_r_l (-4/*ESI*/,saved_a_stack_p_label);
i_move_r_l (-5/*EDI*/,saved_heap_p_label);
+# else
+ i_move_r_id (A_STACK_POINTER,SAVED_A_STACK_P_OFFSET,-5/*EDI*/);
+# endif
}
if (!function_address_parameter)
@@ -4446,8 +4454,12 @@ void code_ccall (char *c_function_name,char *s,int length)
i_jsr_r (function_address_reg);
if (save_state_in_global_variables){
+# ifndef THREAD32
i_move_l_r (saved_a_stack_p_label,-4/*ESI*/);
i_move_l_r (saved_heap_p_label,-5/*EDI*/);
+# else
+ i_move_id_r (SAVED_A_STACK_P_OFFSET,-5/*EDI*/,A_STACK_POINTER);
+# endif
}
if (callee_pops_arguments)
@@ -5389,13 +5401,22 @@ static void save_registers_before_clean_call (void)
# endif
# else
i_sub_i_r (20,B_STACK_POINTER);
-
+# ifndef THREAD32
i_move_r_id (-4/*ESI*/,16,B_STACK_POINTER);
i_move_l_r (saved_a_stack_p_label,-4/*ESI*/);
i_move_r_id (-5/*EDI*/,12,B_STACK_POINTER);
i_move_l_r (saved_heap_p_label,-5/*EDI*/);
+# else
+ if (tlsp_tls_index_label==NULL)
+ tlsp_tls_index_label=enter_label ("tlsp_tls_index",IMPORT_LABEL);
+
+ i_move_r_id (-5/*EDI*/,12,B_STACK_POINTER);
+ instruction_l_r (ILDTLSP,tlsp_tls_index_label,-5/*EDI*/);
+ i_move_r_id (-4/*ESI*/,16,B_STACK_POINTER);
+ i_move_id_r (SAVED_A_STACK_P_OFFSET,-5/*EDI*/,-4/*ESI*/);
+# endif
i_move_r_id (1/*EBX*/,8,B_STACK_POINTER);
i_move_r_id (-1/*ECX*/,4,B_STACK_POINTER);
i_move_r_id (-3/*EBP*/,0,B_STACK_POINTER);
@@ -5464,12 +5485,17 @@ static void restore_registers_after_clean_call (void)
# endif
i_add_i_r (144,B_STACK_POINTER);
# else
+# ifndef THREAD32
i_move_r_l (-4/*ESI*/,saved_a_stack_p_label);
i_move_id_r (16,B_STACK_POINTER,-4/*ESI*/);
i_move_r_l (-5/*EDI*/,saved_heap_p_label);
i_move_id_r (12,B_STACK_POINTER,-5/*EDI*/);
-
+# else
+ i_move_r_id (-4/*ESI*/,SAVED_A_STACK_P_OFFSET,-5/*EDI*/);
+ i_move_id_r (16,B_STACK_POINTER,-4/*ESI*/);
+ i_move_id_r (12,B_STACK_POINTER,-5/*EDI*/);
+# endif
i_move_id_r (8,B_STACK_POINTER,1/*EBX*/);
i_move_id_r (4,B_STACK_POINTER,-1/*ECX*/);
i_move_id_r (0,B_STACK_POINTER,-3/*EBP*/);
diff --git a/cgiwas.c b/cgiwas.c
index acaa9e9..3248c76 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -1660,6 +1660,9 @@ static void w_as_convert_float_condition_instruction (struct instruction *instru
static void w_as_div_rem_i_instruction (struct instruction *instruction,int compute_remainder)
{
int s_reg1,s_reg2,s_reg3,i,sd_reg,i_reg,tmp_reg,abs_i;
+#ifdef THREAD32
+ int tmp2_reg;
+#endif
struct ms ms;
if (instruction->instruction_parameters[0].parameter_type!=P_IMMEDIATE)
@@ -1680,6 +1683,7 @@ static void w_as_div_rem_i_instruction (struct instruction *instruction,int comp
sd_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
tmp_reg=instruction->instruction_parameters[2].parameter_data.reg.r;
+#ifndef THREAD32
if (sd_reg==tmp_reg)
internal_error_in_function ("w_as_div_rem_i_instruction");
@@ -1715,6 +1719,61 @@ static void w_as_div_rem_i_instruction (struct instruction *instruction,int comp
s_reg2=sd_reg;
i_reg=REGISTER_D0;
}
+#else
+ tmp2_reg=instruction->instruction_parameters[3].parameter_data.reg.r;
+
+ if (sd_reg==tmp_reg || sd_reg==tmp2_reg)
+ internal_error_in_function ("w_as_div_rem_i_instruction");
+
+ if (sd_reg==REGISTER_A1){
+ if (tmp2_reg==REGISTER_D0){
+ s_reg2=tmp_reg;
+ } else {
+ if (tmp_reg!=REGISTER_D0)
+ w_as_movl_register_register_newline (REGISTER_D0,tmp_reg);
+ s_reg2=tmp2_reg;
+ }
+
+ w_as_movl_register_register_newline (REGISTER_A1,s_reg2);
+
+ s_reg1=sd_reg;
+ i_reg=REGISTER_D0;
+ } else if (sd_reg==REGISTER_D0){
+ if (tmp2_reg==REGISTER_A1){
+ s_reg2=tmp_reg;
+ } else {
+ if (tmp_reg!=REGISTER_A1)
+ w_as_movl_register_register_newline (REGISTER_A1,tmp_reg);
+ s_reg2=tmp2_reg;
+ }
+
+ w_as_movl_register_register_newline (REGISTER_D0,s_reg2);
+
+ s_reg1=REGISTER_A1;
+ i_reg=REGISTER_A1;
+ } else {
+ if (tmp_reg==REGISTER_D0){
+ if (tmp2_reg!=REGISTER_A1)
+ w_as_movl_register_register_newline (REGISTER_A1,tmp2_reg);
+ } else if (tmp_reg==REGISTER_A1){
+ if (tmp2_reg!=REGISTER_D0)
+ w_as_movl_register_register_newline (REGISTER_D0,tmp2_reg);
+ } else {
+ if (tmp2_reg==REGISTER_D0){
+ w_as_movl_register_register_newline (REGISTER_A1,tmp_reg);
+ } else if (tmp2_reg==REGISTER_A1){
+ w_as_movl_register_register_newline (REGISTER_D0,tmp_reg);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_D0,tmp2_reg);
+ w_as_movl_register_register_newline (REGISTER_A1,tmp_reg);
+ }
+ }
+
+ s_reg1=sd_reg;
+ s_reg2=sd_reg;
+ i_reg=REGISTER_D0;
+ }
+#endif
w_as_opcode_movl();
w_as_immediate_register_newline (ms.m,i_reg);
@@ -1813,6 +1872,7 @@ static void w_as_div_rem_i_instruction (struct instruction *instruction,int comp
w_as_movl_register_register_newline (s_reg3,sd_reg);
}
+#ifndef THREAD32
if (sd_reg==REGISTER_A1){
if (tmp_reg!=REGISTER_D0)
w_as_movl_register_register_newline (tmp_reg,REGISTER_D0);
@@ -1829,6 +1889,32 @@ static void w_as_div_rem_i_instruction (struct instruction *instruction,int comp
w_as_movl_register_register_newline (tmp_reg,REGISTER_A1);
}
}
+#else
+ if (sd_reg==REGISTER_A1){
+ if (tmp2_reg!=REGISTER_D0 && tmp_reg!=REGISTER_D0)
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_D0);
+ } else if (sd_reg==REGISTER_D0){
+ if (tmp2_reg!=REGISTER_A1 && tmp_reg!=REGISTER_A1)
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_A1);
+ } else {
+ if (tmp_reg==REGISTER_D0){
+ if (tmp2_reg!=REGISTER_A1)
+ w_as_movl_register_register_newline (tmp2_reg,REGISTER_A1);
+ } else if (tmp_reg==REGISTER_A1){
+ if (tmp2_reg!=REGISTER_D0)
+ w_as_movl_register_register_newline (tmp2_reg,REGISTER_D0);
+ } else {
+ if (tmp2_reg==REGISTER_D0){
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_A1);
+ } else if (tmp2_reg==REGISTER_A1){
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_D0);
+ } else {
+ w_as_movl_register_register_newline (tmp2_reg,REGISTER_D0);
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_A1);
+ }
+ }
+ }
+#endif
}
static void w_as_sar_31_r (int reg_1)
@@ -1837,6 +1923,7 @@ static void w_as_sar_31_r (int reg_1)
w_as_immediate_register_newline (31,reg_1);
}
+#ifndef THREAD32
static void w_as_div_instruction (struct instruction *instruction,int unsigned_div)
{
int d_reg;
@@ -2006,7 +2093,311 @@ static void w_as_div_instruction (struct instruction *instruction,int unsigned_d
w_as_movl_register_register_newline (REGISTER_O0,REGISTER_A1);
}
}
+#else
+static void w_as_div_instruction (struct instruction *instruction,int unsigned_div)
+{
+ int d_reg,tmp_reg;
+ d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
+ tmp_reg=instruction->instruction_parameters[2].parameter_data.reg.r;
+
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ int i,log2i;
+
+ i=instruction->instruction_parameters[0].parameter_data.i;
+
+ if (unsigned_div==0 && (i & (i-1))==0 && i>0){
+ if (i==1)
+ return;
+
+ log2i=0;
+ while (i>1){
+ i=i>>1;
+ ++log2i;
+ }
+
+ w_as_movl_register_register_newline (d_reg,tmp_reg);
+
+ if (log2i==1){
+ w_as_sar_31_r (tmp_reg);
+
+ w_as_opcode_register_register_newline ("sub",tmp_reg,d_reg);
+ } else {
+ w_as_sar_31_r (d_reg);
+
+ w_as_opcode ("and");
+ w_as_immediate_register_newline ((1<<log2i)-1,d_reg);
+
+ w_as_opcode_register_register_newline ("add",tmp_reg,d_reg);
+ }
+
+ w_as_opcode ("sar");
+ w_as_immediate_register_newline (log2i,d_reg);
+
+ return;
+ }
+
+ internal_error_in_function ("w_as_div_instruction");
+ return;
+ }
+
+ switch (d_reg){
+ case REGISTER_D0:
+ if (tmp_reg==REGISTER_A1){
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ w_as_newline();
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0);
+
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ w_as_scratch_register();
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (REGISTER_O0,REGISTER_A1);
+ }
+ break;
+ case REGISTER_A1:
+ if (tmp_reg==REGISTER_D0){
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (REGISTER_D0,REGISTER_A1);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_D0,tmp_reg);
+
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (REGISTER_D0,REGISTER_A1);
+
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_D0);
+ }
+ break;
+ default:
+ if (tmp_reg==REGISTER_D0){
+ w_as_movl_register_register_newline (d_reg,REGISTER_D0);
+ w_as_movl_register_register_newline (REGISTER_A1,d_reg);
+
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (d_reg,REGISTER_A1);
+ w_as_movl_register_register_newline (REGISTER_D0,d_reg);
+ } else if (tmp_reg==REGISTER_A1){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
+
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,tmp_reg);
+
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
+
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
+
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_A1);
+ }
+ }
+}
+#endif
+
+#ifndef THREAD32
static void w_as_rem_instruction (struct instruction *instruction,int unsigned_rem)
{
int d_reg;
@@ -2117,17 +2508,17 @@ static void w_as_rem_instruction (struct instruction *instruction,int unsigned_r
if (intel_asm)
fprintf (assembly_file,"dword ptr ");
if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
- int r;
+ int r;
- r=instruction->instruction_parameters[0].parameter_data.reg.r;
- if (r==REGISTER_D0)
- r=REGISTER_O0;
- else if (r==REGISTER_A1)
- r=REGISTER_D0;
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=REGISTER_O0;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
- w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
- } else
- w_as_parameter (&instruction->instruction_parameters[0]);
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
}
w_as_newline();
@@ -2161,19 +2552,19 @@ static void w_as_rem_instruction (struct instruction *instruction,int unsigned_r
if (intel_asm)
fprintf (assembly_file,"dword ptr ");
if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
- int r;
+ int r;
- r=instruction->instruction_parameters[0].parameter_data.reg.r;
- if (r==REGISTER_D0)
- r=d_reg;
- else if (r==REGISTER_A1)
- r=REGISTER_O0;
- else if (r==d_reg)
- r=REGISTER_D0;
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_O0;
+ else if (r==d_reg)
+ r=REGISTER_D0;
- w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
- } else
- w_as_parameter (&instruction->instruction_parameters[0]);
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
}
w_as_newline();
@@ -2184,6 +2575,318 @@ static void w_as_rem_instruction (struct instruction *instruction,int unsigned_r
w_as_movl_register_register_newline (REGISTER_O0,REGISTER_A1);
}
}
+#else
+static void w_as_rem_instruction (struct instruction *instruction,int unsigned_rem)
+{
+ int d_reg,tmp_reg;
+
+ d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
+ tmp_reg=instruction->instruction_parameters[2].parameter_data.reg.r;
+
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){
+ int i,log2i;
+
+ i=instruction->instruction_parameters[0].parameter_data.i;
+
+ if (i<0 && i!=0x80000000)
+ i=-i;
+
+ if (! ((i & (i-1))==0 && i>1)){
+ internal_error_in_function ("w_as_rem_instruction");
+ return;
+ }
+
+ log2i=0;
+ while (i>1){
+ i=i>>1;
+ ++log2i;
+ }
+
+ w_as_movl_register_register_newline (d_reg,tmp_reg);
+
+ if (log2i==1){
+ w_as_opcode ("and");
+ w_as_immediate_register_newline (1,d_reg);
+
+ w_as_sar_31_r (tmp_reg);
+
+ w_as_opcode_register_register_newline ("xor",tmp_reg,d_reg);
+ } else {
+ w_as_sar_31_r (tmp_reg);
+
+ w_as_opcode ("and");
+ w_as_immediate_register_newline ((1<<log2i)-1,tmp_reg);
+
+ w_as_opcode_register_register_newline ("add",tmp_reg,d_reg);
+
+ w_as_opcode ("and");
+ w_as_immediate_register_newline ((1<<log2i)-1,d_reg);
+ }
+
+ w_as_opcode_register_register_newline ("sub",tmp_reg,d_reg);
+
+ return;
+ }
+
+ switch (d_reg){
+ case REGISTER_D0:
+ if (tmp_reg==REGISTER_A1){
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ w_as_newline();
+
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,tmp_reg);
+
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ w_as_scratch_register();
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
+ && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
+ {
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,tmp_reg);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
+
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_A1);
+ }
+ break;
+ case REGISTER_A1:
+ if (tmp_reg==REGISTER_D0){
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+ } else {
+ w_as_movl_register_register_newline (REGISTER_D0,tmp_reg);
+
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
+
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=tmp_reg;
+ else if (r==REGISTER_A1)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_D0);
+ }
+ break;
+ default:
+ if (tmp_reg==REGISTER_D0){
+ w_as_movl_register_register_newline (d_reg,REGISTER_D0);
+ w_as_movl_register_register_newline (REGISTER_A1,d_reg);
+
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_A1)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_opcode_register_register_newline ("xchg",d_reg,REGISTER_A1);
+ } else if (tmp_reg==REGISTER_A1){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
+
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (d_reg,REGISTER_D0);
+
+ w_as_movl_register_register_newline (REGISTER_A1,d_reg);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,tmp_reg);
+
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
+
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_register (r);
+ } else {
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
+ int r;
+
+ r=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (r==REGISTER_D0)
+ r=d_reg;
+ else if (r==REGISTER_A1)
+ r=tmp_reg;
+ else if (r==d_reg)
+ r=REGISTER_D0;
+
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,r);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
+ }
+ w_as_newline();
+
+ w_as_movl_register_register_newline (d_reg,REGISTER_D0);
+
+ w_as_movl_register_register_newline (REGISTER_A1,d_reg);
+
+ w_as_movl_register_register_newline (tmp_reg,REGISTER_A1);
+ }
+ }
+}
+#endif
static void w_as_2movl_registers (int reg1,int reg2,int reg3)
{
@@ -2198,6 +2901,7 @@ static void w_as_3movl_registers (int reg1,int reg2,int reg3,int reg4)
w_as_movl_register_register_newline (reg1,reg2);
}
+#ifndef THREAD32
static void w_as_mulud_instruction (struct instruction *instruction)
{
int reg_1,reg_2;
@@ -2355,6 +3059,7 @@ static void w_as_divdu_instruction (struct instruction *instruction)
}
}
}
+#endif
static void w_as_or_r_r (int reg_1,int reg_2)
{
@@ -2999,7 +3704,7 @@ static void fstpl_instruction (int reg0,struct instruction *instruction)
next_fp_instruction->instruction_parameters[0].parameter_flags=flags1;
next2_fp_instruction->instruction_parameters[0].parameter_flags=flags2;
-
+
if (next2_fp_instruction->instruction_icode==IFSUB || next2_fp_instruction->instruction_icode==IFDIV)
next2_fp_instruction->instruction_parameters[1].parameter_flags ^= FP_REVERSE_SUB_DIV_OPERANDS;
@@ -3017,7 +3722,7 @@ static void fstpl_instruction (int reg0,struct instruction *instruction)
}
}
}
-
+
w_as_opcode ("fstp");
w_as_fp_register_newline (reg0+1);
}
@@ -3200,7 +3905,7 @@ static void w_as_monadic_float_instruction (struct instruction *instruction,char
}
case P_INDIRECT:
if (!intel_asm)
- w_as_opcode ("fldl");
+ w_as_opcode ("fldl");
else {
w_as_opcode ("fld");
fprintf (assembly_file,"qword ptr ");
@@ -3210,7 +3915,7 @@ static void w_as_monadic_float_instruction (struct instruction *instruction,char
break;
case P_INDEXED:
if (!intel_asm)
- w_as_opcode ("fldl");
+ w_as_opcode ("fldl");
else {
w_as_opcode ("fld");
fprintf (assembly_file,"qword ptr ");
@@ -3635,7 +4340,9 @@ static struct instruction *w_as_fmoves_instruction (struct instruction *instruct
return instruction;
}
+#ifndef THREAD32
static int int_to_real_scratch_imported=0;
+#endif
static void w_as_fmovel_instruction (struct instruction *instruction)
{
@@ -3643,11 +4350,13 @@ static void w_as_fmovel_instruction (struct instruction *instruction)
if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){
int s_freg;
+#ifndef THREAD32
if (intel_asm && !int_to_real_scratch_imported){
w_as_opcode ("extrn");
fprintf (assembly_file,"%s:near\n","int_to_real_scratch");
int_to_real_scratch_imported=1;
}
+#endif
s_freg=instruction->instruction_parameters[0].parameter_data.reg.r;
if (s_freg!=0){
@@ -3660,7 +4369,11 @@ static void w_as_fmovel_instruction (struct instruction *instruction)
w_as_opcode (!intel_asm ? "fistl" : "fist");
if (intel_asm)
fprintf (assembly_file,"dword ptr ");
+#ifndef THREAD32
w_as_label ("int_to_real_scratch");
+#else
+ w_as_indirect (8,REGISTER_A4);
+#endif
w_as_newline();
w_as_opcode_movl();
@@ -3668,7 +4381,11 @@ static void w_as_fmovel_instruction (struct instruction *instruction)
w_as_register_comma (instruction->instruction_parameters[1].parameter_data.reg.r);
fprintf (assembly_file,"dword ptr ");
}
+#ifndef THREAD32
w_as_label ("int_to_real_scratch");
+#else
+ w_as_indirect (8,REGISTER_A4);
+#endif
if (!intel_asm)
w_as_comma_register (instruction->instruction_parameters[1].parameter_data.reg.r);
w_as_newline();
@@ -3677,18 +4394,23 @@ static void w_as_fmovel_instruction (struct instruction *instruction)
} else {
switch (instruction->instruction_parameters[0].parameter_type){
case P_REGISTER:
+#ifndef THREAD32
if (intel_asm && !int_to_real_scratch_imported){
w_as_opcode ("extrn");
fprintf (assembly_file,"%s:near\n","int_to_real_scratch");
int_to_real_scratch_imported=1;
}
-
+#endif
w_as_opcode_movl();
if (!intel_asm)
w_as_register_comma (instruction->instruction_parameters[0].parameter_data.reg.r);
else
fprintf (assembly_file,"dword ptr ");
+#ifndef THREAD32
w_as_label ("int_to_real_scratch");
+#else
+ w_as_indirect (8,REGISTER_A4);
+#endif
if (intel_asm)
w_as_comma_register (instruction->instruction_parameters[0].parameter_data.reg.r);
w_as_newline();
@@ -3818,6 +4540,42 @@ static void w_as_rtsp_instruction (void)
w_as_newline();
}
+#ifdef THREAD32
+static void w_as_ldtlsp_instruction (struct instruction *instruction)
+{
+ int reg;
+
+ reg=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ w_as_opcode ("mov");
+ if (intel_asm){
+ w_as_register_comma (reg);
+ fprintf (assembly_file,"dword ptr ");
+ }
+ if (instruction->instruction_parameters[0].parameter_data.l->label_number!=0)
+ w_as_local_label (instruction->instruction_parameters[0].parameter_data.l->label_number);
+ else
+ w_as_label (instruction->instruction_parameters[0].parameter_data.l->label_name);
+ if (!intel_asm)
+ w_as_comma_register (reg);
+ w_as_newline();
+
+ w_as_opcode ("mov");
+ if (intel_asm){
+ w_as_register_comma (reg);
+ fprintf (assembly_file,"dword ptr fs:[0x0e10+");
+ w_as_register (reg);
+ fprintf (assembly_file,"*4]");
+ } else {
+ fprintf (assembly_file,"fs:0x0e10(,");
+ w_as_register (reg);
+ fprintf (assembly_file,",4)");
+ w_as_comma_register (reg);
+ }
+ w_as_newline();
+}
+#endif
+
static void w_as_instructions (register struct instruction *instruction)
{
while (instruction!=NULL){
@@ -4004,12 +4762,14 @@ static void w_as_instructions (register struct instruction *instruction)
case ISBB:
w_as_dyadic_instruction (instruction,intel_asm ? "sbb" : "sbbl");
break;
+#ifndef THREAD32
case IMULUD:
w_as_mulud_instruction (instruction);
break;
case IDIVDU:
w_as_divdu_instruction (instruction);
break;
+#endif
case IFLOORDIV:
w_as_floordiv_mod_instruction (instruction,0);
break;
@@ -4150,6 +4910,11 @@ static void w_as_instructions (register struct instruction *instruction)
case IFSINCOS:
w_as_fsincos_instruction (instruction);
break;
+#ifdef THREAD32
+ case ILDTLSP:
+ w_as_ldtlsp_instruction (instruction);
+ break;
+#endif
case IFTST:
default:
internal_error_in_function ("w_as_instructions");
@@ -4221,17 +4986,32 @@ static void w_as_garbage_collect_test (register struct basic_block *block)
first_call_and_jump=new_call_and_jump;
last_call_and_jump=new_call_and_jump;
+#ifdef THREAD32
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (HEAP_POINTER);
+ w_as_indirect (0,REGISTER_A4);
+ if (!intel_asm)
+ w_as_comma_register (HEAP_POINTER);
+ w_as_newline();
+#endif
+
if (n_cells<=8){
w_as_opcode (intel_asm ? "cmp" : "cmpl");
if (intel_asm){
w_as_register_comma (HEAP_POINTER);
fprintf (assembly_file,"dword ptr ");
}
+#ifndef THREAD32
fprintf (assembly_file,"end_heap");
+#else
+ w_as_indirect (4,REGISTER_A4);
+#endif
if (!intel_asm)
w_as_comma_register (HEAP_POINTER);
w_as_newline();
} else {
+#ifndef THREAD32
w_as_opcode ("lea");
if (intel_asm)
w_as_scratch_register_comma();
@@ -4239,13 +5019,21 @@ static void w_as_garbage_collect_test (register struct basic_block *block)
if (!intel_asm)
w_as_comma_scratch_register();
w_as_newline();
+#else
+ w_as_opcode (intel_asm ? "add" : "addl");
+ w_as_immediate_register_newline ((n_cells-8)<<2,HEAP_POINTER);
+#endif
w_as_opcode (intel_asm ? "cmp" : "cmpl");
if (intel_asm){
w_as_scratch_register_comma();
fprintf (assembly_file,"dword ptr ");
}
+#ifndef THREAD32
fprintf (assembly_file,"end_heap");
+#else
+ w_as_indirect (4,REGISTER_A4);
+#endif
if (!intel_asm)
w_as_comma_scratch_register();
w_as_newline();
@@ -4256,6 +5044,18 @@ static void w_as_garbage_collect_test (register struct basic_block *block)
w_as_newline ();
w_as_define_internal_label (label_id_2);
+
+#ifdef THREAD32
+ if (n_cells>8){
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (HEAP_POINTER);
+ w_as_indirect (0,REGISTER_A4);
+ if (!intel_asm)
+ w_as_comma_register (HEAP_POINTER);
+ w_as_newline();
+ }
+#endif
}
static void w_as_call_and_jump (struct call_and_jump *call_and_jump)
@@ -4352,7 +5152,9 @@ void initialize_write_assembly (FILE *ass_file)
in_data_section=0;
first_call_and_jump=NULL;
+#ifndef THREAD32
int_to_real_scratch_imported=0;
+#endif
if (intel_asm){
w_as_opcode (".486");
diff --git a/cglin.c b/cglin.c
index 67ec0fc..0ca5605 100644
--- a/cglin.c
+++ b/cglin.c
@@ -937,7 +937,7 @@ void i_call_r (int register_1,int frame_size)
}
#endif
-#ifdef I486
+#if defined (I486) && !defined (THREAD32)
void i_divdu_r_r_r (int register_1,int register_2,int register_3)
{
struct instruction *instruction;
@@ -1332,9 +1332,10 @@ static void i_move_d_r (LABEL *descriptor,int arity,int register_1)
parameter_data.i=register_1);
}
+#ifndef THREAD32
void i_move_id_id (int offset_1,int register_1,int offset_2,int register_2)
{
- register struct instruction *instruction;
+ struct instruction *instruction;
instruction=i_new_instruction2 (IMOVE);
@@ -1346,6 +1347,7 @@ void i_move_id_id (int offset_1,int register_1,int offset_2,int register_2)
instruction->instruction_parameters[1].parameter_offset=offset_2;
instruction->instruction_parameters[1].parameter_data.i=register_2;
}
+#endif
void i_move_id_r (int offset,int register_1,int register_2)
{
@@ -1436,11 +1438,12 @@ void i_move_id_r (int offset,int register_1,int register_2)
#endif
#if defined (M68000) || defined (I486)
+# ifndef THREAD32
static void i_move_id_x (int offset_1,int register_1,int offset_2,int register_2,int register_3)
{
- register struct instruction *instruction;
- register struct index_registers *index_registers;
-
+ struct instruction *instruction;
+ struct index_registers *index_registers;
+
instruction=i_new_instruction
(IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers));
index_registers=(struct index_registers *)&instruction->instruction_parameters[2];
@@ -1456,6 +1459,7 @@ static void i_move_id_x (int offset_1,int register_1,int offset_2,int register_2
index_registers->a_reg.r=register_2;
index_registers->d_reg.r=register_3;
}
+# endif
#endif
void i_move_l_r (LABEL *label,int register_1)
@@ -1637,6 +1641,28 @@ void i_move_r_r (int register_1,int register_2)
parameter_data.i=register_2);
}
+#ifdef THREAD32
+static void i_move_r_x (int register_1,int offset_2,int register_2,int register_3)
+{
+ struct instruction *instruction;
+ struct index_registers *index_registers;
+
+ instruction=i_new_instruction
+ (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers));
+ index_registers=(struct index_registers *)&instruction->instruction_parameters[2];
+
+ instruction->instruction_parameters[0].parameter_type=P_REGISTER;
+ instruction->instruction_parameters[0].parameter_data.i=register_1;
+
+ instruction->instruction_parameters[1].parameter_type=P_INDEXED;
+ instruction->instruction_parameters[1].parameter_offset=offset_2;
+ instruction->instruction_parameters[1].parameter_data.ir=index_registers;
+
+ index_registers->a_reg.r=register_2;
+ index_registers->d_reg.r=register_3;
+}
+#endif
+
static void i_move_x_r (int offset,int register_1,int register_2,int register_3)
{
struct instruction *instruction;
@@ -1657,10 +1683,11 @@ static void i_move_x_r (int offset,int register_1,int register_2,int register_3)
instruction->instruction_parameters[1].parameter_data.i=register_3;
}
+#ifndef THREAD32
static void i_move_x_id (int offset_1,int register_1,int register_2,int offset_2,int register_3)
{
- register struct instruction *instruction;
- register struct index_registers *index_registers;
+ struct instruction *instruction;
+ struct index_registers *index_registers;
instruction=i_new_instruction
(IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers));
@@ -1677,6 +1704,7 @@ static void i_move_x_id (int offset_1,int register_1,int register_2,int offset_2
instruction->instruction_parameters[1].parameter_offset=offset_2;
instruction->instruction_parameters[1].parameter_data.i=register_3;
}
+#endif
#if defined (M68000)
static void i_move_x_pi (int offset,int register_1,int register_2,int register_3)
@@ -1779,7 +1807,7 @@ void i_movew_r_pd (int register_1,int register_2)
}
#endif
-#ifdef I486
+#if defined (I486) && !defined (THREAD32)
void i_mulud_r_r (int register_1,int register_2)
{
struct instruction *instruction;
@@ -2041,7 +2069,7 @@ static int get_free_register_number (register struct register_set *r_s_p)
static void free_register_number (struct register_set *r_s_p,unsigned int reg_n)
{
struct register_list *r_list;
- register unsigned int bit_n;
+ unsigned int bit_n;
if (reg_n<r_s_p->r_s_first_free)
r_s_p->r_s_first_free=reg_n;
@@ -2060,7 +2088,7 @@ static void free_register_number (struct register_set *r_s_p,unsigned int reg_n)
static void allocate_register_number (struct register_set *r_s_p,unsigned int reg_n)
{
struct register_list *r_list;
- register unsigned int bit_n;
+ unsigned int bit_n;
bit_n=reg_n;
r_list=&r_s_p->r_s_list;
@@ -2076,7 +2104,7 @@ static void allocate_register_number (struct register_set *r_s_p,unsigned int re
static int try_allocate_register_number (int reg_n)
{
struct register_list *r_list;
- register unsigned int bit_n;
+ unsigned int bit_n;
if (is_d_register (reg_n)){
r_list=&free_dregisters.r_s_list;
@@ -2100,8 +2128,8 @@ static int try_allocate_register_number (int reg_n)
static int try_get_real_dregister_number (VOID)
{
- register struct register_list *r_list;
- register unsigned int reg_n;
+ struct register_list *r_list;
+ unsigned int reg_n;
ULONG vector;
reg_n=free_dregisters.r_s_first_free;
@@ -2334,7 +2362,7 @@ static void ad_to_parameter (ADDRESS *ad_p,struct parameter *parameter_p)
}
#if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD)
-#define FP_REG_LAST_USE 4
+# define FP_REG_LAST_USE 4
#endif
static int fad_to_parameter_without_freeing_fregister (ADDRESS *ad_p,struct parameter *parameter_p)
@@ -2444,6 +2472,35 @@ static void instruction_ad_id (int instruction_code,ADDRESS *ad_p,int offset,int
instruction->instruction_parameters[1].parameter_data.i=register_1;
}
+static void i_move_ad_id (ADDRESS *ad_p,int offset,int register_1)
+{
+ struct instruction *instruction;
+
+ instruction=i_new_instruction2 (IMOVE);
+
+ ad_to_parameter (ad_p,&instruction->instruction_parameters[0]);
+
+#ifdef THREAD32
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT ||
+ instruction->instruction_parameters[0].parameter_type==P_INDEXED){
+ int reg;
+
+ reg=get_dregister();
+
+ instruction->instruction_parameters[1].parameter_type=P_REGISTER;
+ instruction->instruction_parameters[1].parameter_data.i=reg;
+
+ i_move_r_id (reg,offset,register_1);
+ free_register (reg);
+ return;
+ }
+#endif
+
+ instruction->instruction_parameters[1].parameter_type=P_INDIRECT;
+ instruction->instruction_parameters[1].parameter_offset=offset;
+ instruction->instruction_parameters[1].parameter_data.i=register_1;
+}
+
#ifdef G_POWER
static void i_move_ad_idu (ADDRESS *ad_p,int offset,int register_1)
{
@@ -2459,6 +2516,41 @@ static void instruction_ad_id (int instruction_code,ADDRESS *ad_p,int offset,int
}
#endif
+#ifdef THREAD32
+static void i_move_ad_x (ADDRESS *ad_p,int offset,int register_1,int register_2)
+{
+ struct instruction *instruction;
+ struct index_registers *index_registers;
+
+ instruction=i_new_instruction
+ (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers));
+ index_registers=(struct index_registers *)&instruction->instruction_parameters[2];
+
+ ad_to_parameter (ad_p,&instruction->instruction_parameters[0]);
+
+ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT ||
+ instruction->instruction_parameters[0].parameter_type==P_INDEXED){
+ int reg;
+
+ reg=get_dregister();
+
+ instruction->instruction_parameters[1].parameter_type=P_REGISTER;
+ instruction->instruction_parameters[1].parameter_data.i=reg;
+
+ i_move_r_x (reg,offset,register_1,register_2);
+ free_register (reg);
+ return;
+ }
+
+ instruction->instruction_parameters[1].parameter_type=P_INDEXED;
+ instruction->instruction_parameters[1].parameter_offset=offset;
+ instruction->instruction_parameters[1].parameter_data.ir=index_registers;
+
+ index_registers->a_reg.r=register_1;
+ index_registers->d_reg.r=register_2;
+}
+#endif
+
#ifdef M68000
static void instruction_ad_pd (int instruction_code,ADDRESS *ad_p,int register_1)
{
@@ -2543,7 +2635,7 @@ static void instruction_l (int instruction_code,LABEL *label)
instruction->instruction_parameters[0].parameter_data.l=label;
}
-#if defined (THREAD64)
+#if defined (THREAD32) || defined (THREAD64)
void instruction_l_r (int instruction_code,LABEL *label,int register_1)
{
struct instruction *instruction;
@@ -2573,6 +2665,27 @@ static void instruction_ad_r_r (int instruction_code,ADDRESS *ad_p,int register_
parameter_data.i=register_2);
}
+#ifdef THREAD32
+static void instruction_i_r_r_r (int instruction_code,int i,int register_1,int register_2,int register_3)
+{
+ struct instruction *instruction;
+
+ instruction=i_new_instruction (instruction_code,4,4*sizeof (struct parameter));
+
+ S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE,
+ parameter_data.imm=i);
+
+ S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER,
+ parameter_data.i=register_1);
+
+ S2 (instruction->instruction_parameters[2], parameter_type=P_REGISTER,
+ parameter_data.i=register_2);
+
+ S2 (instruction->instruction_parameters[3], parameter_type=P_REGISTER,
+ parameter_data.i=register_3);
+}
+#endif
+
#ifdef I486
static void instruction_r_r_r_i (int instruction_code,int register_1,int register_2,int register_3,int i)
{
@@ -2618,8 +2731,8 @@ void instruction_pd (int instruction_code,int register_1)
static void instruction_ad_x (int instruction_code,ADDRESS *ad_p,int offset,int register_1,int register_2)
{
- register struct instruction *instruction;
- register struct index_registers *index_registers;
+ struct instruction *instruction;
+ struct index_registers *index_registers;
instruction=i_new_instruction
(instruction_code,2,2*sizeof (struct parameter)+sizeof (struct index_registers));
@@ -3206,7 +3319,7 @@ static void register_node (INSTRUCTION_GRAPH graph,int reg)
global_block.block_graph_d_register_parameter_node[d_reg_num (reg)]=graph;
}
-static void float_register_node (register INSTRUCTION_GRAPH graph,int reg)
+static void float_register_node (INSTRUCTION_GRAPH graph,int reg)
{
graph->instruction_code=GFREGISTER;
graph->instruction_parameters[0].i=reg;
@@ -3637,7 +3750,7 @@ static int linearize_not_condition (INSTRUCTION_GRAPH graph);
static int linearize_condition (INSTRUCTION_GRAPH graph)
{
int condition;
-
+
switch (graph->instruction_code){
case GCMP_EQ:
condition=compare_node (graph,CEQ,CEQ);
@@ -3967,7 +4080,17 @@ static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH
if (ad_1.ad_mode==P_IMMEDIATE){
if (i_instruction_code==IDIVU || i_instruction_code==IREMU){
in_data_register (&ad_1);
+# ifndef THREAD32
instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+# else
+ {
+ int tmp_reg;
+
+ tmp_reg=get_dregister();
+ instruction_ad_r_r (i_instruction_code,&ad_1,ad_2.ad_register,tmp_reg);
+ free_register (tmp_reg);
+ }
+# endif
} else {
CleanInt i;
@@ -3980,27 +4103,65 @@ static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH
i=-i;
if ((i & (i-1))==0 && (i_instruction_code==IREM ? i>1 : i>0)){
+# ifndef THREAD32
instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+# else
+ int tmp_reg;
+
+ tmp_reg=get_dregister();
+ instruction_ad_r_r (i_instruction_code,&ad_1,ad_2.ad_register,tmp_reg);
+ free_dregister (tmp_reg);
+# endif
# ifndef G_A64
} else if (i>1 || (i<-1 && i!=0x80000000)){
# else
} else if (i>1 || (i<-1 && i!=0x8000000000000000ll)){
# endif
+# ifndef THREAD32
int tmp_reg;
tmp_reg=get_dregister();
instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg);
free_dregister (tmp_reg);
+# else
+ int tmp_reg,tmp2_reg;
+
+ tmp_reg=get_dregister();
+ tmp2_reg=get_dregister();
+ instruction_i_r_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,i,ad_2.ad_register,tmp_reg,tmp2_reg);
+ free_dregister (tmp2_reg);
+ free_dregister (tmp_reg);
+# endif
} else {
in_data_register (&ad_1);
+# ifndef THREAD32
instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+# else
+ {
+ int tmp_reg;
+
+ tmp_reg=get_dregister();
+ instruction_ad_r_r (i_instruction_code,&ad_1,ad_2.ad_register,tmp_reg);
+ free_dregister (tmp_reg);
+ }
+# endif
}
}
} else {
to_data_addressing_mode (&ad_1);
if (ad_1.ad_mode==P_INDEXED)
in_data_register (&ad_1);
+# ifndef THREAD32
instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+# else
+ {
+ int tmp_reg;
+
+ tmp_reg=get_dregister();
+ instruction_ad_r_r (i_instruction_code,&ad_1,ad_2.ad_register,tmp_reg);
+ free_dregister (tmp_reg);
+ }
+# endif
}
# else
instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
@@ -4219,7 +4380,8 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE
int reg_1,reg_2;
graph=result_graph->instruction_parameters[0].p;
-
+
+#ifndef THREAD32
if (graph->instruction_code==GMULUD){
INSTRUCTION_GRAPH graph_1,graph_2;
@@ -4256,7 +4418,9 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE
if (--*ad_3.ad_count_p==0)
free_register (ad_3.ad_register);
i_divdu_r_r_r (ad_3.ad_register,reg_1,reg_2);
- } else if (graph->instruction_code==GADDDU){
+ } else
+#endif
+ if (graph->instruction_code==GADDDU){
ADDRESS ad_3,ad_4;
linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1,
@@ -4746,9 +4910,22 @@ static void move_float_ad_id (ADDRESS *ad_p,int offset,int areg)
free_aregister (ad_p->ad_register);
} else {
#endif
+#ifndef THREAD32
i_move_id_id (ad_p->ad_offset,ad_p->ad_register,offset,areg);
-#ifndef G_A64
+# ifndef G_A64
i_move_id_id (ad_p->ad_offset+4,ad_p->ad_register,offset+4,areg);
+# endif
+#else
+ {
+ int reg;
+
+ reg=get_dregister();
+ i_move_id_r (ad_p->ad_offset,ad_p->ad_register,reg);
+ i_move_r_id (reg,offset,areg);
+ i_move_id_r (ad_p->ad_offset+4,ad_p->ad_register,reg);
+ i_move_r_id (reg,offset+4,areg);
+ free_register (reg);
+ }
#endif
if (--*ad_p->ad_count_p==0)
free_aregister (ad_p->ad_register);
@@ -4796,13 +4973,14 @@ static void move_float_ad_id (ADDRESS *ad_p,int offset,int areg)
return;
}
#endif
+#ifndef THREAD32
i_move_x_id (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,offset,areg);
if (--*i_ad_p->ad_count_p==0)
free_aregister (i_ad_p->ad_areg);
-#ifndef G_A64
-# if defined (M68000) || defined (I486)
+# ifndef G_A64
+# if defined (M68000) || defined (I486)
i_move_x_id (i_ad_p->ad_offset+(4<<2),i_ad_p->ad_areg,i_ad_p->ad_dreg,offset+4,areg);
-# else
+# else
{
int a_reg;
@@ -4811,14 +4989,41 @@ static void move_float_ad_id (ADDRESS *ad_p,int offset,int areg)
i_move_id_id (4,a_reg,offset+4,areg);
free_aregister (a_reg);
}
+# endif
# endif
+#else
+ {
+ int reg;
+
+ reg=get_dregister();
+ i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,reg);
+ i_move_r_id (reg,offset,areg);
+ i_move_x_r (i_ad_p->ad_offset+(4<<2),i_ad_p->ad_areg,i_ad_p->ad_dreg,reg);
+ i_move_r_id (reg,offset+4,areg);
+ free_register (reg);
+ if (--*i_ad_p->ad_count_p==0)
+ free_aregister (i_ad_p->ad_areg);
+ }
#endif
if (--*i_ad_p->ad_count_p2==0)
free_dregister (i_ad_p->ad_dreg);
} else {
+#ifndef THREAD32
i_move_id_id (i_ad_p->ad_offset,i_ad_p->ad_register,offset,areg);
-#ifndef G_A64
+# ifndef G_A64
i_move_id_id (i_ad_p->ad_offset+4,i_ad_p->ad_register,offset+4,areg);
+# endif
+#else
+ {
+ int reg;
+
+ reg=get_dregister();
+ i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,reg);
+ i_move_r_id (reg,offset,areg);
+ i_move_id_r (i_ad_p->ad_offset+4,i_ad_p->ad_register,reg);
+ i_move_r_id (reg,offset+4,areg);
+ free_register (reg);
+ }
#endif
if (--*i_ad_p->ad_count_p==0)
free_aregister (i_ad_p->ad_register);
@@ -4839,7 +5044,7 @@ static void move_float_ad_id (ADDRESS *ad_p,int offset,int areg)
}
}
-static void linearize_load_graph (register INSTRUCTION_GRAPH load_graph)
+static void linearize_load_graph (INSTRUCTION_GRAPH load_graph)
{
if (load_graph!=NULL){
if (load_graph->node_count>0){
@@ -4986,11 +5191,11 @@ static void linearize_create_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,int
#ifdef M68000
move_float_ad_pi (&ad_a[argument_number],HEAP_POINTER);
#else
-# ifdef G_POWER
+# ifdef G_POWER
move_float_ad_id (&ad_a[argument_number],heap_offset+4,HEAP_POINTER);
-# else
+# else
move_float_ad_id (&ad_a[argument_number],heap_offset,HEAP_POINTER);
-# endif
+# endif
heap_offset+=8;
#endif
#ifndef G_A64
@@ -5000,7 +5205,7 @@ static void linearize_create_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,int
#ifdef M68000
instruction_ad_pi (IMOVE,&ad_a[argument_number],HEAP_POINTER);
#else
-# ifdef G_POWER
+# ifdef G_POWER
if (ad_a[argument_number].ad_mode==P_STORE_HP_INSTRUCTION){
struct instruction *instruction;
@@ -5010,10 +5215,10 @@ static void linearize_create_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,int
heap_pointer_offset_in_basic_block+heap_offset+STACK_ELEMENT_SIZE
-instruction->instruction_parameters[1].parameter_data.i;
} else
- instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset+STACK_ELEMENT_SIZE,HEAP_POINTER);
-# else
- instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset,HEAP_POINTER);
-# endif
+ i_move_ad_id (&ad_a[argument_number],heap_offset+STACK_ELEMENT_SIZE,HEAP_POINTER);
+# else
+ i_move_ad_id (&ad_a[argument_number],heap_offset,HEAP_POINTER);
+# endif
heap_offset+=STACK_ELEMENT_SIZE;
#endif
}
@@ -5203,7 +5408,7 @@ linearize_store_create_operator (int offset,int stack_pointer,INSTRUCTION_GRAPH
-instruction->instruction_parameters[1].parameter_data.i;
} else
# endif
- instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset,HEAP_POINTER);
+ i_move_ad_id (&ad_a[argument_number],heap_offset,HEAP_POINTER);
heap_offset+=STACK_ELEMENT_SIZE;
#endif
}
@@ -5240,11 +5445,11 @@ static void linearize_fill_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
--n_arguments;
ad_a=evaluate_arguments (graph->instruction_parameters,n_arguments);
-
+
if (n_arguments==2 && graph->instruction_parameters[1].p!=NULL){
in_address_register (&ad_a[0]);
reg_1=reg_2=ad_a[0].ad_register;
- instruction_ad_id (IMOVE,&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
+ i_move_ad_id (&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
if (--*ad_a[0].ad_count_p==0 && graph->node_count==0)
free_aregister (reg_2);
} else if ( n_arguments==3 && graph->instruction_parameters[1].p!=NULL
@@ -5258,17 +5463,17 @@ static void linearize_fill_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
move_float_ad_id (&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
} else
#ifdef G_A64
- instruction_ad_id (IMOVE,&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
+ i_move_ad_id (&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
if (ad_a[2].ad_mode>=100){
ad_a[2].ad_mode-=100;
move_float_ad_id (&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2);
} else
- instruction_ad_id (IMOVE,&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2);
+ i_move_ad_id (&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2);
#else
{
- instruction_ad_id (IMOVE,&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
- instruction_ad_id (IMOVE,&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2);
+ i_move_ad_id (&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
+ i_move_ad_id (&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2);
}
#endif
if (--*ad_a[0].ad_count_p==0 && graph->node_count==0)
@@ -5329,9 +5534,9 @@ static void linearize_fill_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
if (argument_number!=n_arguments-1)
instruction_ad_pi (IMOVE,&ad_a[argument_number],reg_1);
else
- instruction_ad_id (IMOVE,&ad_a[argument_number],0,reg_1);
+ i_move_ad_id (&ad_a[argument_number],0,reg_1);
#else
- instruction_ad_id (IMOVE,&ad_a[argument_number],offset,reg_1);
+ i_move_ad_id (&ad_a[argument_number],offset,reg_1);
offset+=STACK_ELEMENT_SIZE;
#endif
}
@@ -5414,9 +5619,22 @@ static void move_float_ad_x (ADDRESS *ad_p,int offset,int areg,int dreg)
free_aregister (ad_p->ad_register);
} else {
# endif
+# ifndef THREAD32
i_move_id_x (ad_p->ad_offset,ad_p->ad_register,offset,areg,dreg);
-# ifndef G_A64
+# ifndef G_A64
i_move_id_x (ad_p->ad_offset+4,ad_p->ad_register,offset+(4<<2),areg,dreg);
+# endif
+# else
+ {
+ int reg;
+
+ reg=get_dregister();
+ i_move_id_r (ad_p->ad_offset,ad_p->ad_register,reg);
+ i_move_r_x (reg,offset,areg,dreg);
+ i_move_id_r (ad_p->ad_offset+4,ad_p->ad_register,reg);
+ i_move_r_x (reg,offset+(4<<2),areg,dreg);
+ free_register (reg);
+ }
# endif
if (--*ad_p->ad_count_p==0)
free_aregister (ad_p->ad_register);
@@ -5483,7 +5701,7 @@ static void linearize_fill_r_operator (register INSTRUCTION_GRAPH graph,register
in_address_register (&ad_a[0]);
reg_2=ad_a[0].ad_register;
- instruction_ad_id (IMOVE,&ad_a[1],0,reg_2);
+ i_move_ad_id (&ad_a[1],0,reg_2);
move_float_ad_id (&ad_a[2],STACK_ELEMENT_SIZE,reg_2);
if (graph->node_count==0)
@@ -5577,9 +5795,9 @@ static void linearize_store_fill_operator (INSTRUCTION_GRAPH s_graph,INSTRUCTION
if (argument_number!=n_arguments-1)
instruction_ad_pi (IMOVE,&ad_a[argument_number],reg_1);
else
- instruction_ad_id (IMOVE,&ad_a[argument_number],0,reg_1);
+ i_move_ad_id (&ad_a[argument_number],0,reg_1);
#else
- instruction_ad_id (IMOVE,&ad_a[argument_number],offset,reg_1);
+ i_move_ad_id (&ad_a[argument_number],offset,reg_1);
offset+=STACK_ELEMENT_SIZE;
#endif
}
@@ -5830,7 +6048,7 @@ static void linearize_fmovemi_operator (INSTRUCTION_GRAPH graph,register ADDRESS
ad_p->ad_count_p=&graph->node_count;
}
-static void linearize_copy_operator (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p)
+static void linearize_copy_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
ADDRESS ad;
int areg_1,areg_2;
@@ -5853,9 +6071,24 @@ static void linearize_copy_operator (register INSTRUCTION_GRAPH graph,register A
i_move_pi_id (areg_1,4,areg_2);
i_move_pi_id (areg_1,8,areg_2);
#else
+# ifndef THREAD32
i_move_id_id (0,areg_1,0,areg_2);
i_move_id_id (STACK_ELEMENT_SIZE,areg_1,STACK_ELEMENT_SIZE,areg_2);
i_move_id_id (2*STACK_ELEMENT_SIZE,areg_1,2*STACK_ELEMENT_SIZE,areg_2);
+# else
+ {
+ int reg;
+
+ reg=get_dregister();
+ i_move_id_r (0,areg_1,reg);
+ i_move_r_id (reg,0,areg_2);
+ i_move_id_r (STACK_ELEMENT_SIZE,areg_1,reg);
+ i_move_r_id (reg,STACK_ELEMENT_SIZE,areg_2);
+ i_move_id_r (2*STACK_ELEMENT_SIZE,areg_1,reg);
+ i_move_r_id (reg,2*STACK_ELEMENT_SIZE,areg_2);
+ free_register (reg);
+ }
+# endif
#endif
if (--*ad.ad_count_p==0)
@@ -6643,7 +6876,7 @@ static void linearize_flow_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
#endif
#ifdef G_A64
-static void linearize_tof_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad_p)
+static void linearize_tof_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
ADDRESS ad_1;
@@ -6651,7 +6884,7 @@ static void linearize_tof_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad
local_data_offset-=FLOAT_SIZE;
- instruction_ad_id (IMOVE,&ad_1,local_data_offset,B_STACK_POINTER);
+ i_move_ad_id (&ad_1,local_data_offset,B_STACK_POINTER);
if (graph->node_count>1){
int freg;
@@ -6662,7 +6895,7 @@ static void linearize_tof_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad
ad_p->ad_mode=P_F_REGISTER;
ad_p->ad_register=freg;
ad_p->ad_count_p=&graph->node_count;
-
+
float_register_node (graph,freg);
} else {
ad_p->ad_mode=P_INDIRECT;
@@ -6705,8 +6938,8 @@ static void linearize_fjoin_operator (INSTRUCTION_GRAPH graph,register ADDRESS *
local_data_offset-=FLOAT_SIZE;
- instruction_ad_id (IMOVE,&ad_2,local_data_offset+4,B_STACK_POINTER);
- instruction_ad_id (IMOVE,&ad_1,local_data_offset,B_STACK_POINTER);
+ i_move_ad_id (&ad_2,local_data_offset+4,B_STACK_POINTER);
+ i_move_ad_id (&ad_1,local_data_offset,B_STACK_POINTER);
if (graph->node_count>1){
int freg;
@@ -6732,7 +6965,7 @@ static void linearize_fjoin_operator (INSTRUCTION_GRAPH graph,register ADDRESS *
static int float_compare_node (INSTRUCTION_GRAPH graph,int i_test_1,int i_test_2)
{
ADDRESS ad_1,ad_2;
-
+
linearize_float_graph (graph->instruction_parameters[0].p,&ad_1);
linearize_float_graph (graph->instruction_parameters[1].p,&ad_2);
@@ -7185,7 +7418,7 @@ static void linearize_two_float_results_operator (INSTRUCTION_GRAPH result_graph
}
#endif
-static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p)
+static void linearize_float_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
switch (graph->instruction_code){
case GFREGISTER:
@@ -7200,7 +7433,6 @@ static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADD
ad_p->ad_count=1+1;
break;
case GFLOAD:
- {
if (graph->node_count<=1){
ad_p->ad_mode=P_INDIRECT;
ad_p->ad_count_p=&ad_p->ad_count;
@@ -7223,7 +7455,6 @@ static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADD
float_register_node (graph,reg_1);
}
return;
- }
case GFLOAD_I:
if (graph->node_count<=1){
ad_p->ad_mode=P_F_IMMEDIATE;
@@ -7252,9 +7483,7 @@ static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADD
if (graph->node_count<=1){
ad_p->ad_mode=P_INDIRECT;
ad_p->ad_offset=graph->instruction_parameters[0].i;
- /* added 26-7-97 */
--graph->node_count;
- /* */
} else {
int reg_1;
@@ -7392,10 +7621,10 @@ static void linearize_fstore_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p);
static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p);
#endif
-static void linearize_fstore_r_operator (register INSTRUCTION_GRAPH graph)
+static void linearize_fstore_r_operator (INSTRUCTION_GRAPH graph)
{
INSTRUCTION_GRAPH *register_graph_1_p,*register_graph_2_p;
- register int reg_1;
+ int reg_1;
ADDRESS ad_1;
linearize_float_graph (graph->instruction_parameters[1].p,&ad_1);
@@ -7414,7 +7643,7 @@ static void linearize_fstore_r_operator (register INSTRUCTION_GRAPH graph)
}
if (ad_1.ad_mode==P_F_REGISTER){
- register int reg_2;
+ int reg_2;
reg_2=ad_1.ad_register;
@@ -7442,7 +7671,7 @@ static void linearize_fstore_r_operator (register INSTRUCTION_GRAPH graph)
*register_graph_2_p=graph;
} else {
#endif
- register int reg_2;
+ int reg_2;
reg_2=get_fregister();
if ((unsigned)reg_2<(unsigned)N_FLOAT_PARAMETER_REGISTERS)
@@ -7474,15 +7703,12 @@ static void linearize_fstore_r_operator (register INSTRUCTION_GRAPH graph)
} else {
if (ad_1.ad_mode==P_INDIRECT)
--*ad_1.ad_count_p;
- if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL
- && (*register_graph_1_p)->node_count>0)
- {
- register int reg_2;
+ if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL && (*register_graph_1_p)->node_count>0){
+ int reg_2;
reg_2=get_fregister();
if ((unsigned)reg_2<(unsigned)N_FLOAT_PARAMETER_REGISTERS)
- register_graph_2_p=
- &global_block.block_graph_f_register_parameter_node [reg_2];
+ register_graph_2_p=&global_block.block_graph_f_register_parameter_node [reg_2];
else
register_graph_2_p=NULL;
@@ -7497,6 +7723,7 @@ static void linearize_fstore_r_operator (register INSTRUCTION_GRAPH graph)
}
if (ad_1.ad_mode==P_INDIRECT)
++*ad_1.ad_count_p;
+
instruction_ad_fr (IFMOVE,&ad_1,reg_1);
}
@@ -7516,14 +7743,18 @@ static void linearize_create_r_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,i
#ifndef M68000
# ifdef I486
+# ifdef G_A64
+ if (offset_from_heap_register+(2<<3) >= 127){
+# else
if (offset_from_heap_register+(3<<2) >= 127){
+# endif
# else
-# ifdef G_POWER
+# ifdef G_POWER
if (offset_from_heap_register+(3<<2) >= 32767){
heap_pointer_offset_in_basic_block+=offset_from_heap_register;
-# else
+# else
if (offset_from_heap_register+(3<<2) >= 4096){
-# endif
+# endif
# endif
i_add_i_r (offset_from_heap_register,HEAP_POINTER);
IF_G_POWER (last_heap_pointer_update=last_instruction;)
@@ -7558,10 +7789,10 @@ static void linearize_create_r_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,i
move_float_ad_pi (&ad_2,HEAP_POINTER);
#else
# ifdef G_POWER
- instruction_ad_id (IMOVE,&ad_1,offset_from_heap_register+4,HEAP_POINTER);
+ i_move_ad_id (&ad_1,offset_from_heap_register+4,HEAP_POINTER);
move_float_ad_id (&ad_2,offset_from_heap_register+4+STACK_ELEMENT_SIZE,HEAP_POINTER);
# else
- instruction_ad_id (IMOVE,&ad_1,offset_from_heap_register,HEAP_POINTER);
+ i_move_ad_id (&ad_1,offset_from_heap_register,HEAP_POINTER);
move_float_ad_id (&ad_2,offset_from_heap_register+STACK_ELEMENT_SIZE,HEAP_POINTER);
# endif
# ifdef G_A64
@@ -8406,10 +8637,21 @@ static void linearize_store_x_operator (int i_instruction_code,INSTRUCTION_GRAPH
in_address_register (ad_p);
if (graph_3==NULL){
+#ifndef THREAD32
if (i_instruction_code!=IMOVE && ad_1.ad_mode!=P_IMMEDIATE)
in_data_register (&ad_1);
instruction_ad_id (i_instruction_code,&ad_1,offset>>2,ad_p->ad_register);
+#else
+ if (i_instruction_code==IMOVE){
+ i_move_ad_id (&ad_1,offset>>2,ad_p->ad_register);
+ } else {
+ if (ad_1.ad_mode!=P_IMMEDIATE)
+ in_data_register (&ad_1);
+
+ instruction_ad_id (i_instruction_code,&ad_1,offset>>2,ad_p->ad_register);
+ }
+#endif
#if defined (sparc) || defined (G_POWER)
} else if (offset!=0){
if (i_instruction_code!=IMOVE && ad_1.ad_mode!=P_IMMEDIATE)
@@ -8425,10 +8667,11 @@ static void linearize_store_x_operator (int i_instruction_code,INSTRUCTION_GRAPH
in_register (&ad_1);
#endif
+#ifndef THREAD32
if (i_instruction_code!=IMOVE && ad_1.ad_mode!=P_IMMEDIATE
-#ifdef M68000
+# ifdef M68000
&& ad_1.ad_mode!=P_INDEXED
-#endif
+# endif
)
in_data_register (&ad_1);
@@ -8436,6 +8679,21 @@ static void linearize_store_x_operator (int i_instruction_code,INSTRUCTION_GRAPH
free_dregister (ad_3.ad_register);
instruction_ad_x (i_instruction_code,&ad_1,offset,ad_p->ad_register,ad_3.ad_register);
+#else
+ if (i_instruction_code==IMOVE){
+ i_move_ad_x (&ad_1,offset,ad_p->ad_register,ad_3.ad_register);
+ if (--*ad_3.ad_count_p==0)
+ free_dregister (ad_3.ad_register);
+ } else {
+ if (ad_1.ad_mode!=P_IMMEDIATE)
+ in_data_register (&ad_1);
+
+ if (--*ad_3.ad_count_p==0)
+ free_dregister (ad_3.ad_register);
+
+ instruction_ad_x (i_instruction_code,&ad_1,offset,ad_p->ad_register,ad_3.ad_register);
+ }
+#endif
}
if (graph->node_count>1){
@@ -8812,7 +9070,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
linearize_load_graph (graph->instruction_parameters[3].p);
- instruction_ad_id (IMOVE,ad_p,offset,stack_pointer);
+ i_move_ad_id (ad_p,offset,stack_pointer);
return;
}
case GBEFORE0:
@@ -8914,7 +9172,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
return;
case GLOAD_B_X:
linearize_load_b_x_operator (graph,ad_p);
- return;
+ return;
#ifdef G_AI64
case GLOAD_S_X:
linearize_load_s_x_operator (graph,ad_p,0);
@@ -9596,6 +9854,8 @@ static void show_parameter (struct parameter *parameter)
case P_POST_INCREMENT:
printf ("(A%d)+",a_reg_num (parameter->parameter_data.reg.r));
break;
+#endif
+#if defined (M68000) || defined (I486)
case P_PRE_DECREMENT:
printf ("-(A%d)",a_reg_num (parameter->parameter_data.reg.r));
break;
diff --git a/cgopt.c b/cgopt.c
index a4881f9..d343bc4 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -421,7 +421,10 @@ static int get_argument_size (int instruction_code)
IF_G_RISC (case IADDI: case ILSLI:)
IF_G_SPARC (case IADDO: case ISUBO: )
#ifdef I486
- case IDIVI: case IREMI: case IREMU: case IMULUD: case IDIVDU:
+ case IDIVI: case IREMI: case IREMU:
+# ifndef THREAD32
+ case IMULUD: case IDIVDU:
+# endif
case IFLOORDIV: case IMOD:
#endif
#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER)
@@ -674,10 +677,16 @@ static void compute_maximum_b_stack_offsets (register int b_offset)
instruction->instruction_icode!=IMOVEM &&
#endif
#ifdef I486
+# ifdef THREAD32
+ instruction->instruction_icode!=IDIV &&
+ instruction->instruction_icode!=IDIVU &&
+# endif
instruction->instruction_icode!=IDIVI &&
instruction->instruction_icode!=IREMI &&
instruction->instruction_icode!=IREMU &&
+# ifndef THREAD32
instruction->instruction_icode!=IDIVDU &&
+# endif
instruction->instruction_icode!=IASR_S &&
instruction->instruction_icode!=ILSL_S &&
instruction->instruction_icode!=ILSR_S &&
@@ -916,10 +925,17 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
switch (instruction->instruction_arity){
default:
- if (instruction->instruction_icode!=IDIVI &&
+ if (
+# ifdef THREAD32
+ instruction->instruction_icode!=IDIV &&
+ instruction->instruction_icode!=IDIVU &&
+# endif
+ instruction->instruction_icode!=IDIVI &&
instruction->instruction_icode!=IREMI &&
instruction->instruction_icode!=IREMU &&
+# ifndef THREAD32
instruction->instruction_icode!=IDIVDU &&
+# endif
instruction->instruction_icode!=IASR_S &&
instruction->instruction_icode!=ILSL_S &&
instruction->instruction_icode!=ILSR_S &&
@@ -1155,7 +1171,7 @@ void optimize_heap_pointer_increment (struct basic_block *block,int offset_from_
internal_error_in_function ("optimize_heap_pointer_increment");
}
}
- continue;
+ continue;
case IFMOVE:
/* can be optimized, not yet implemented
if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT &&
@@ -1577,11 +1593,20 @@ IF_G_POWER ( case IUMULH: )
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
break;
- case IDIV: case IREM: case IDIVU: case IREMU: case IMULUD:
+ case IDIV: case IREM: case IDIVU: case IREMU:
+# ifdef THREAD32
+ use_parameter (&instruction->instruction_parameters[1]);
+ use_parameter (&instruction->instruction_parameters[0]);
+ define_parameter (&instruction->instruction_parameters[2]);
+ break;
+# endif
+# ifndef THREAD32
+ case IMULUD:
define_scratch_register();
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
break;
+# endif
case IMOVE:
if ((instruction->instruction_parameters[0].parameter_type==P_INDIRECT ||
instruction->instruction_parameters[0].parameter_type==P_INDEXED) &&
@@ -1594,11 +1619,14 @@ IF_G_POWER ( case IUMULH: )
#endif
#ifdef I486
case IDIVI: case IREMI:
-# ifdef I486_USE_SCRATCH_REGISTER
+# if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32)
define_scratch_register();
# endif
use_parameter (&instruction->instruction_parameters[1]);
define_parameter (&instruction->instruction_parameters[2]);
+# ifdef THREAD32
+ define_parameter (&instruction->instruction_parameters[3]);
+# endif
break;
#endif
case IFMOVE: case IFMOVEL: case ILEA:
@@ -1691,7 +1719,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
use_parameter (&instruction->instruction_parameters[0]);
break;
#endif
-#ifdef I486
+#if defined (I486) && !defined (THREAD32)
case IDIVDU:
# ifdef I486_USE_SCRATCH_REGISTER
define_scratch_register();
@@ -2741,7 +2769,7 @@ static void move_2_register ( int reg_n,int real_reg_n,int use_flag,
reg_uses[reg_n].reg=real_reg_n;
reg_alloc[real_reg_n].altered=reg_alloc[old_real_reg_n].altered;
-
+
if (use_flag!=DEF)
insert_move (old_real_reg_n,real_reg_n,register_flag);
}
@@ -3836,7 +3864,7 @@ static void use_scratch_register (void)
{
int reg,real_reg_n,instruction_n;
struct scratch_register_next_uses *scratch_register_next_use;
-
+
scratch_register_next_use=scratch_register_next_uses;
scratch_register_next_uses=scratch_register_next_use->scratch_register_next;
@@ -3873,6 +3901,11 @@ static void allocate_registers (struct basic_block *basic_block)
previous_instruction=NULL;
instruction=basic_block->block_instructions;
+
+#ifdef THREAD32
+ allocate_scratch_register = basic_block->block_n_new_heap_cells==0;
+#endif
+
while (instruction!=NULL){
switch (instruction->instruction_icode){
case IADD: case IAND:
@@ -3898,15 +3931,29 @@ IF_G_POWER ( case IUMULH: )
break;
#ifdef I486_USE_SCRATCH_REGISTER
case IASR: case ILSL: case ILSR: case IROTL: case IROTR:
- if (instruction->instruction_parameters[0].parameter_type!=P_IMMEDIATE)
+ if (instruction->instruction_parameters[0].parameter_type!=P_IMMEDIATE){
use_scratch_register();
- instruction_use_2 (instruction,USE_DEF);
- allocate_scratch_register=1;
+ instruction_use_2 (instruction,USE_DEF);
+ allocate_scratch_register=1;
+ } else
+ instruction_use_2 (instruction,USE_DEF);
break;
case IDIV: case IREM: case IDIVU: case IREMU:
+# ifndef THREAD32
use_scratch_register();
instruction_use_2 (instruction,USE_DEF);
allocate_scratch_register=1;
+# else
+ if (instruction->instruction_parameters[0].parameter_type!=P_IMMEDIATE)
+ use_3_same_type_registers
+ (&instruction->instruction_parameters[0].parameter_data.reg,USE,
+ &instruction->instruction_parameters[1].parameter_data.reg,USE_DEF,
+ &instruction->instruction_parameters[2].parameter_data.reg,DEF,D_REGISTER);
+ else
+ use_2_same_type_registers
+ (&instruction->instruction_parameters[1].parameter_data.reg,USE_DEF,
+ &instruction->instruction_parameters[2].parameter_data.reg,DEF,D_REGISTER);
+# endif
break;
#endif
case ICMP:
@@ -3994,7 +4041,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
case IEXG:
instruction_usedef_usedef (instruction);
break;
-#ifdef I486
+#if defined (I486) && !defined (THREAD32)
case IMULUD:
# ifdef I486_USE_SCRATCH_REGISTER
use_scratch_register();
@@ -4033,14 +4080,21 @@ IF_G_RISC (case IADDI: case ILSLI:)
#endif
#ifdef I486
case IDIVI: case IREMI:
-# ifdef I486_USE_SCRATCH_REGISTER
+# ifndef THREAD32
+# ifdef I486_USE_SCRATCH_REGISTER
use_scratch_register();
-# endif
- register_use_2
+# endif
+ register_use_2
(&instruction->instruction_parameters[1].parameter_data.reg,USE_DEF,
&instruction->instruction_parameters[2].parameter_data.reg,DEF);
-# ifdef I486_USE_SCRATCH_REGISTER
+# ifdef I486_USE_SCRATCH_REGISTER
allocate_scratch_register=1;
+# endif
+# else
+ use_3_same_type_registers
+ (&instruction->instruction_parameters[1].parameter_data.reg,USE_DEF,
+ &instruction->instruction_parameters[2].parameter_data.reg,DEF,
+ &instruction->instruction_parameters[3].parameter_data.reg,DEF,D_REGISTER);
# endif
break;
#endif
@@ -4052,7 +4106,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
instruction_bmove_use_use_use (instruction);
break;
#endif
-#ifdef I486
+#if defined (I486) && !defined (THREAD32)
case IDIVDU:
# ifdef I486_USE_SCRATCH_REGISTER
use_scratch_register();
@@ -4187,7 +4241,7 @@ int do_register_allocation
end_d_registers &= ~((unsigned)(2|1)<<d_reg_num (REGISTER_D2));
}
#endif
-
+
end_a_registers |= ((unsigned)1<<a_reg_num (A_STACK_POINTER)) |
((unsigned)1<<a_reg_num (B_STACK_POINTER)) |
#ifndef I486
@@ -4199,7 +4253,16 @@ int do_register_allocation
((unsigned)1<<a_reg_num (REGISTER_A9)) |
((unsigned)1<<a_reg_num (REGISTER_A10)) |
#endif
+#ifndef THREAD32
((unsigned)1<<a_reg_num (HEAP_POINTER));
+#else
+ 0;
+#endif
+
+#ifdef THREAD32
+ if (basic_block->block_n_new_heap_cells!=0)
+ end_a_registers |= ((unsigned)1<<a_reg_num (HEAP_POINTER));
+#endif
#ifdef NEW_R_ALLOC
r_reg_uses_block=(struct register_use*)memory_allocate ((highest_a_register+highest_d_register) * sizeof (struct register_use));
diff --git a/cgrconst.h b/cgrconst.h
index 9c87cca..77d45a2 100644
--- a/cgrconst.h
+++ b/cgrconst.h
@@ -32,7 +32,11 @@ enum { REGISTER_FP0, REGISTER_FP1, REGISTER_FP2, REGISTER_FP3,
# define N_FLOAT_PARAMETER_REGISTERS 8
# else
# define A_STACK_POINTER REGISTER_A3
+# ifndef THREAD32
# define HEAP_POINTER REGISTER_A4
+# else
+# define HEAP_POINTER REGISTER_A2
+# endif
# define B_STACK_POINTER REGISTER_A5
# define N_ADDRESS_PARAMETER_REGISTERS 2
# define N_DATA_PARAMETER_REGISTERS 2
diff --git a/cgstack.c b/cgstack.c
index 30bcd66..b06f7c7 100644
--- a/cgstack.c
+++ b/cgstack.c
@@ -73,8 +73,6 @@ extern unsigned int end_a_registers,end_d_registers,end_f_registers;
/* from cglin.c */
extern int local_data_offset;
-#pragma segment Code4
-
#define allocate_struct_from_heap(a) (struct a*)allocate_memory_from_heap(sizeof (struct a))
INSTRUCTION_GRAPH s_get_a (int offset)
@@ -395,11 +393,11 @@ void init_b_stack (int b_stack_size,ULONG vector[])
register_graph=g_register (num_to_d_reg (number_of_data_register_parameters-1-n));
s_put_b_l (data_offsets[n],register_graph,register_graph);
}
-
+
for (n=0; n<number_of_float_register_parameters; ++n){
INSTRUCTION_GRAPH register_graph,h_graph,l_graph;
- register int offset;
-
+ int offset;
+
register_graph=g_fregister (number_of_float_register_parameters-1-n);
offset=float_offsets[n];
@@ -513,7 +511,7 @@ void init_ab_stack (int a_stack_size,int b_stack_size,ULONG vector[])
for (n=0; n<number_of_float_register_parameters; ++n){
INSTRUCTION_GRAPH register_graph,h_graph,l_graph;
- register int offset;
+ int offset;
register_graph=g_fregister (number_of_float_register_parameters-1-n);
@@ -704,8 +702,8 @@ int get_a_stack_size (VOID)
static int count_b_stack_size (ULONG *vector_p[],struct b_stack *b_stack,int b_stack_top_offset)
{
- register struct b_stack *first_b_element,*b_element;
- register int b_stack_size,offset,i;
+ struct b_stack *first_b_element,*b_element;
+ int b_stack_size,offset,i;
ULONG *vector;
b_stack_size=0;
@@ -770,8 +768,8 @@ static int count_b_stack_size (ULONG *vector_p[],struct b_stack *b_stack,int b_s
static int count_b_stack_size_2 (ULONG *vector_p[],struct b_stack *b_stack,int b_stack_top_offset)
{
- register struct b_stack *first_b_element,*b_element;
- register int b_stack_size,offset,i;
+ struct b_stack *first_b_element,*b_element;
+ int b_stack_size,offset,i;
ULONG *vector;
b_stack_size=0;
@@ -807,9 +805,9 @@ static int count_b_stack_size_2 (ULONG *vector_p[],struct b_stack *b_stack,int b
}
b_element=first_b_element;
-
+
for (i=0; i<b_stack_size; ){
- register struct b_stack *next_b_element;
+ struct b_stack *next_b_element;
INSTRUCTION_GRAPH graph,next_graph;
#ifdef G_A64
@@ -851,8 +849,8 @@ int get_b_stack_size (ULONG *vector_p[])
static void a_stack_load_register_values (int n_parameters,int n_address_parameter_registers)
{
- register struct a_stack **element_p;
- register int parameter_n;
+ struct a_stack **element_p;
+ int parameter_n;
if (n_parameters>n_address_parameter_registers)
n_parameters=n_address_parameter_registers;
@@ -1033,8 +1031,8 @@ static void b_stack_load_register_values (int n_parameters,ULONG vector[],int n_
#endif
)
{
- register struct b_stack **element_p;
- register int parameter_n;
+ struct b_stack **element_p;
+ int parameter_n;
int number_of_d_register_parameters,number_of_f_register_parameters_m_2;
#ifdef MORE_PARAMETER_REGISTERS
@@ -1055,7 +1053,7 @@ static void b_stack_load_register_values (int n_parameters,ULONG vector[],int n_
while (*element_p!=NULL && (*element_p)->b_stack_offset<required_offset)
element_p=&(*element_p)->b_stack_next;
-
+
if (!test_bit (vector,parameter_n)
? number_of_d_register_parameters++ < n_data_parameter_registers
#ifdef MORE_PARAMETER_REGISTERS
@@ -1068,7 +1066,7 @@ static void b_stack_load_register_values (int n_parameters,ULONG vector[],int n_
#endif
{
if (*element_p!=NULL && (*element_p)->b_stack_offset==required_offset){
- register struct b_stack *element;
+ struct b_stack *element;
element=*element_p;
if (element->b_stack_flags & ELEMENT_MAY_BE_REMOVED && element->b_stack_graph==NULL){
@@ -1281,10 +1279,10 @@ static void b_stack_stores (int n_parameters,ULONG vector[],int n_data_parameter
for (n=0; n<number_of_f_register_parameters; ++n)
if (f_graphs[n]!=NULL){
- register int f_reg_n;
-
+ int f_reg_n;
+
f_reg_n=number_of_f_register_parameters-1-n;
-
+
end_f_registers |= ((unsigned)1<<f_reg_n);
*f_graphs_p[n]=g_fstore_r (f_reg_n,f_graphs[n]);
@@ -1331,9 +1329,9 @@ static int set_basic_block_begin_d_registers
#endif
)
{
- register int offset,stack_displacement;
- register int n_d_registers,n_f_registers,all_parameters_in_registers;
- register int n_data_parameter_registers;
+ int offset,stack_displacement;
+ int n_d_registers,n_f_registers,all_parameters_in_registers;
+ int n_data_parameter_registers;
n_data_parameter_registers =
(parallel_flag ? N_DATA_PARAMETER_REGISTERS-1 : N_DATA_PARAMETER_REGISTERS)
@@ -1365,8 +1363,8 @@ static int set_basic_block_begin_d_registers
all_parameters_in_registers=1;
for (offset=0; offset<b_stack_size; ++offset){
- register INSTRUCTION_GRAPH graph;
-
+ INSTRUCTION_GRAPH graph;
+
if (!test_bit (vector,offset)){
if (n_d_registers<=0)
all_parameters_in_registers=0;
@@ -1378,9 +1376,9 @@ static int set_basic_block_begin_d_registers
while (*element_p!=NULL && (*element_p)->b_stack_offset<offset)
element_p=&(*element_p)->b_stack_next;
-
+
if (*element_p!=NULL && (*element_p)->b_stack_offset==offset){
- register struct b_stack *element;
+ struct b_stack *element;
element=*element_p;
@@ -1486,7 +1484,7 @@ static int set_basic_block_begin_d_registers
element_p=&(*element_p)->b_stack_next;
} else {
- register struct b_stack *new_element;
+ struct b_stack *new_element;
graph=g_new_node (GREGISTER,0,sizeof (union instruction_parameter));
#ifdef MORE_PARAMETER_REGISTERS
@@ -1524,7 +1522,7 @@ static int set_basic_block_begin_d_registers
else {
INSTRUCTION_GRAPH r_graph;
int f_register_not_used_flag;
- register struct b_stack *element;
+ struct b_stack *element;
--n_f_registers;
@@ -1681,7 +1679,7 @@ static int set_basic_block_begin_d_registers
static void compute_b_load_offsets (register struct b_stack *b_element,int offset)
{
for (; b_element!=NULL; b_element=b_element->b_stack_next){
- register INSTRUCTION_GRAPH load_graph;
+ INSTRUCTION_GRAPH load_graph;
load_graph=b_element->b_stack_load_graph;
@@ -2879,7 +2877,7 @@ static void mark_stack_graphs_1
(b_element_1==NULL || b_element_1->b_stack_offset!=offset+1))
#endif
{
- register struct b_stack *new_element;
+ struct b_stack *new_element;
INSTRUCTION_GRAPH f_graph,l_graph,h_graph;
/* printf ("%d# ",offset); */
@@ -2929,7 +2927,7 @@ static void mark_stack_graphs_1
b_element_2=next_b_element_2;
#endif
} else {
- register struct b_stack *new_element;
+ struct b_stack *new_element;
INSTRUCTION_GRAPH graph;
/* printf ("%d ",offset); */
@@ -2972,7 +2970,7 @@ static void mark_stack_graphs_1
&& (b_element_1==NULL || b_element_1->b_stack_offset!=offset+1)
&& mc68881_flag)
{
- register struct b_stack *new_element;
+ struct b_stack *new_element;
INSTRUCTION_GRAPH f_graph,l_graph,h_graph;
/* printf ("%d$# ",offset); */
@@ -3022,7 +3020,7 @@ static void mark_stack_graphs_1
++offset;
#endif
} else {
- register struct b_stack *new_element;
+ struct b_stack *new_element;
INSTRUCTION_GRAPH graph;
/* printf ("%d$ ",offset); */
@@ -3242,7 +3240,12 @@ void linearize_stack_graphs (VOID)
if (graphs!=NULL){
calculate_and_linearize_graphs (n_elements,graphs);
-
+
+#ifdef THREAD32
+ if (last_block->block_n_new_heap_cells!=0)
+ i_move_r_id (HEAP_POINTER,0,REGISTER_A4);
+#endif
+
memory_free (graphs);
} else
allocate_registers();
@@ -3321,6 +3324,11 @@ void linearize_stack_graphs_with_overflow_test (INSTRUCTION_GRAPH test_overflow_
# endif
#endif
+#ifdef THREAD32
+ if (last_block->block_n_new_heap_cells!=0)
+ i_move_r_id (HEAP_POINTER,0,REGISTER_A4);
+#endif
+
memory_free (graphs);
}
@@ -3492,7 +3500,7 @@ int adjust_stack_pointers_without_altering_condition_codes (int float_condition,
struct basic_block *allocate_empty_basic_block (VOID)
{
- register struct basic_block *block;
+ struct basic_block *block;
block=(struct basic_block*)fast_memory_allocate (sizeof (struct basic_block));
block->block_next=NULL;
@@ -3753,7 +3761,7 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register
static void generate_code_for_basic_block (struct block_graph *next_block_graph)
{
- register struct block_graph *block_graph;
+ struct block_graph *block_graph;
struct basic_block *old_last_block;
struct instruction *block_instructions,*block_last_instruction;
int n_allocated_d_regs,n_allocated_f_regs,n_data_parameter_registers;
@@ -3805,7 +3813,7 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph)
#endif
)
--end_b_stack_size;
-
+
a_stack_load_register_values (block_graph->block_graph_end_a_stack_size,N_ADDRESS_PARAMETER_REGISTERS);
b_stack_load_register_values (end_b_stack_size,block_graph->block_graph_end_stack_vector,n_data_parameter_registers
#ifdef MORE_PARAMETER_REGISTERS
@@ -3826,7 +3834,7 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph)
switch (block_graph->block_graph_kind){
case JSR_EVAL_BLOCK:
{
- register int n,b_stack_size,n_data_parameter_registers;
+ int n,b_stack_size,n_data_parameter_registers;
n_data_parameter_registers = parallel_flag ? N_DATA_PARAMETER_REGISTERS-1 : N_DATA_PARAMETER_REGISTERS;
@@ -3893,7 +3901,7 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph)
#endif
case JSR_BLOCK:
{
- register int b_offset;
+ int b_offset;
#if ! (defined (sparc) || defined (G_POWER))
b_offset=local_register_allocation_and_adjust_a_stack_pointer
@@ -4201,7 +4209,7 @@ void generate_code_for_previous_blocks (int jmp_jsr_or_rtn_flag)
(&block_graph->block_graph_end_stack_vector,
block_graph->block_graph_b_stack,
block_graph->block_graph_b_stack_top_offset);
-
+
vector=block_graph->block_graph_end_stack_vector;
a_stack_size=optimize_jsr_eval (block_graph,a_stack_size,next_block_graph);
@@ -4210,7 +4218,7 @@ void generate_code_for_previous_blocks (int jmp_jsr_or_rtn_flag)
a_stack_size=N_ADDRESS_PARAMETER_REGISTERS;
block_graph->block_graph_end_a_stack_size=a_stack_size;
block_graph->block_graph_end_b_stack_size=b_stack_size;
-
+
if (block_graph->block_graph_next!=NULL)
next_block_graph->block_graph_block->block_n_begin_a_parameter_registers=a_stack_size;
else