summaryrefslogtreecommitdiff
path: root/cgias.c
diff options
context:
space:
mode:
Diffstat (limited to 'cgias.c')
-rw-r--r--cgias.c697
1 files changed, 694 insertions, 3 deletions
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);