summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgaas.c138
-rw-r--r--cgawas.c80
-rw-r--r--cgiwas.c4
3 files changed, 147 insertions, 75 deletions
diff --git a/cgaas.c b/cgaas.c
index e24e5bb..1195812 100644
--- a/cgaas.c
+++ b/cgaas.c
@@ -2830,13 +2830,13 @@ static void as_div_rem_i_instruction (struct instruction *instruction,int comput
}
}
-static void as_div_instruction (struct instruction *instruction)
+static void as_div_instruction (struct instruction *instruction,int unsigned_div)
{
- int d_reg;
+ int d_reg,opcode2;
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_div==0){
int_64 i;
int log2i;
@@ -2886,25 +2886,31 @@ static void as_div_instruction (struct instruction *instruction)
return;
}
+ opcode2=unsigned_div ? 0060 : 0070;
+
switch (d_reg){
case REGISTER_D0:
as_move_r_r (REGISTER_A1,REGISTER_O0);
-
- /*cqo*/
- store_c (0x48);
- store_c (0231);
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else {
+ /*cqo*/
+ store_c (0x48);
+ store_c (0231);
+ }
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
- as_r (0367,0070,REGISTER_O0);
+ as_r (0367,opcode2,REGISTER_O0);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_O0,REGISTER_A1);
break;
@@ -2912,10 +2918,14 @@ static void as_div_instruction (struct instruction *instruction)
as_move_r_r (REGISTER_D0,REGISTER_O0);
as_move_r_r (REGISTER_A1,REGISTER_D0);
- /*cqo*/
- store_c (0x48);
- store_c (0231);
-
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else {
+ /*cqo*/
+ store_c (0x48);
+ store_c (0231);
+ }
+
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2926,7 +2936,7 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -2936,9 +2946,9 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
- as_parameter (00367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (00367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_D0,REGISTER_A1);
as_move_r_r (REGISTER_O0,REGISTER_D0);
@@ -2946,11 +2956,15 @@ static void as_div_instruction (struct instruction *instruction)
default:
as_move_r_r (REGISTER_A1,REGISTER_O0);
as_xchg_d0_rn (reg_num (d_reg)); /* xchg d_reg,D0 */
-
- /*cqo*/
- store_c (0x48);
- store_c (0231);
-
+
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else {
+ /*cqo*/
+ store_c (0x48);
+ store_c (0231);
+ }
+
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2963,7 +2977,7 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -2975,22 +2989,22 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_xchg_d0_rn (reg_num (d_reg)); /* xchg d_reg,D0 */
as_move_r_r (REGISTER_O0,REGISTER_A1);
}
}
-static void as_rem_instruction (struct instruction *instruction)
+static void as_rem_instruction (struct instruction *instruction,int unsigned_rem)
{
- int d_reg;
+ int d_reg,opcode2;
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){
int log2i;
int_64 i;
@@ -3057,13 +3071,19 @@ static void as_rem_instruction (struct instruction *instruction)
return;
}
+ opcode2=unsigned_rem ? 0060 : 0070;
+
switch (d_reg){
case REGISTER_D0:
as_move_r_r (REGISTER_A1,REGISTER_O0);
- /*cqo*/
- store_c (0x48);
- store_c (0231);
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else {
+ /*cqo*/
+ store_c (0x48);
+ store_c (0231);
+ }
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
@@ -3073,9 +3093,9 @@ static void as_rem_instruction (struct instruction *instruction)
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_A1,REGISTER_D0);
as_move_r_r (REGISTER_O0,REGISTER_A1);
@@ -3083,10 +3103,15 @@ static void as_rem_instruction (struct instruction *instruction)
case REGISTER_A1:
as_move_r_r (REGISTER_D0,REGISTER_O0);
as_move_r_r (REGISTER_A1,REGISTER_D0);
-
- /*cqo*/
- store_c (0x48);
- store_c (0231);
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else {
+ /*cqo*/
+ store_c (0x48);
+ store_c (0231);
+ }
+
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -3097,7 +3122,7 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -3107,19 +3132,24 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_O0,REGISTER_D0);
break;
default:
as_move_r_r (REGISTER_A1,REGISTER_O0);
as_xchg_d0_rn (reg_num (d_reg)); /* xchg d_reg,D0 */
-
- /*cqo*/
- store_c (0x48);
- store_c (0231);
+
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else {
+ /*cqo*/
+ store_c (0x48);
+ store_c (0231);
+ }
+
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -3132,7 +3162,7 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -3144,9 +3174,9 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (d_reg,REGISTER_D0);
as_move_r_r (REGISTER_A1,d_reg);
@@ -3826,7 +3856,7 @@ static void as_float_neg_instruction (struct instruction *instruction)
as_f_id (0xf2,0x10,instruction->instruction_parameters[0].parameter_offset,
/* movsd */ instruction->instruction_parameters[0].parameter_data.reg.r,d_freg);
else
- as_f_id (0x66,0x12,instruction->instruction_parameters[0].parameter_offset,
+ as_f_id (0x66,0x12,instruction->instruction_parameters[0].parameter_offset,
/* movlpd */ instruction->instruction_parameters[0].parameter_data.reg.r,d_freg);
break;
case P_INDEXED:
@@ -3834,7 +3864,7 @@ static void as_float_neg_instruction (struct instruction *instruction)
as_f_x (0xf2,0x10,instruction->instruction_parameters[0].parameter_offset,
/* movsd */ instruction->instruction_parameters[0].parameter_data.ir,d_freg);
else
- as_f_x (0x66,0x12,instruction->instruction_parameters[0].parameter_offset,
+ as_f_x (0x66,0x12,instruction->instruction_parameters[0].parameter_offset,
/* movlpd */ instruction->instruction_parameters[0].parameter_data.ir,d_freg);
break;
case P_F_IMMEDIATE:
@@ -4351,17 +4381,23 @@ static void as_instructions (struct instruction *instruction)
as_mul_instruction (instruction);
break;
case IDIV:
- as_div_instruction (instruction);
+ as_div_instruction (instruction,0);
break;
case IDIVI:
as_div_rem_i_instruction (instruction,0);
break;
+ case IDIVU:
+ as_div_instruction (instruction,1);
+ break;
case IREM:
- as_rem_instruction (instruction);
+ as_rem_instruction (instruction,0);
break;
case IREMI:
as_div_rem_i_instruction (instruction,1);
break;
+ case IREMU:
+ as_rem_instruction (instruction,1);
+ break;
case IAND:
as_logic_instruction (instruction,0043,040,045);
break;
diff --git a/cgawas.c b/cgawas.c
index d41b8e4..da5d5a0 100644
--- a/cgawas.c
+++ b/cgawas.c
@@ -2161,13 +2161,13 @@ static void w_as_div_rem_i_instruction (struct instruction *instruction,int comp
}
}
-static void w_as_div_instruction (struct instruction *instruction)
+static void w_as_div_instruction (struct instruction *instruction,int unsigned_div)
{
int d_reg;
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_div==0){
int_64 i;
int log2i;
@@ -2222,9 +2222,14 @@ static void w_as_div_instruction (struct instruction *instruction)
case REGISTER_D0:
w_as_movq_register_register_newline (REGISTER_A1,REGISTER_O0);
- w_as_instruction_without_parameters ("cqo");
-
- w_as_opcode (intel_asm ? "idiv" : "idivq");
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divq");
+ } else {
+ w_as_instruction_without_parameters ("cqo");
+ w_as_opcode (intel_asm ? "idiv" : "idivq");
+ }
+
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
@@ -2248,9 +2253,14 @@ static void w_as_div_instruction (struct instruction *instruction)
w_as_movq_register_register_newline (REGISTER_A1,REGISTER_D0);
- w_as_instruction_without_parameters ("cqo");
-
- w_as_opcode (intel_asm ? "idiv" : "idivq");
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divq");
+ } else {
+ w_as_instruction_without_parameters ("cqo");
+ w_as_opcode (intel_asm ? "idiv" : "idivq");
+ }
+
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2288,9 +2298,14 @@ static void w_as_div_instruction (struct instruction *instruction)
w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
- w_as_instruction_without_parameters ("cqo");
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divq");
+ } else {
+ w_as_instruction_without_parameters ("cqo");
+ w_as_opcode (intel_asm ? "idiv" : "idivq");
+ }
- w_as_opcode (intel_asm ? "idiv" : "idivq");
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2329,13 +2344,13 @@ static void w_as_div_instruction (struct instruction *instruction)
}
}
-static void w_as_rem_instruction (struct instruction *instruction)
+static void w_as_rem_instruction (struct instruction *instruction,int unsigned_rem)
{
int d_reg;
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){
int log2i;
int_64 i;
@@ -2398,9 +2413,14 @@ static void w_as_rem_instruction (struct instruction *instruction)
case REGISTER_D0:
w_as_movq_register_register_newline (REGISTER_A1,REGISTER_O0);
- w_as_instruction_without_parameters ("cqo");
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divq");
+ } else {
+ w_as_instruction_without_parameters ("cqo");
+ w_as_opcode (intel_asm ? "idiv" : "idivq");
+ }
- w_as_opcode (intel_asm ? "idiv" : "idivq");
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
@@ -2427,9 +2447,14 @@ static void w_as_rem_instruction (struct instruction *instruction)
w_as_movq_register_register_newline (REGISTER_A1,REGISTER_D0);
- w_as_instruction_without_parameters ("cqo");
-
- w_as_opcode (intel_asm ? "idiv" : "idivq");
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divq");
+ } else {
+ w_as_instruction_without_parameters ("cqo");
+ w_as_opcode (intel_asm ? "idiv" : "idivq");
+ }
+
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2465,9 +2490,14 @@ static void w_as_rem_instruction (struct instruction *instruction)
w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
- w_as_instruction_without_parameters ("cqo");
-
- w_as_opcode (intel_asm ? "idiv" : "idivq");
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divq");
+ } else {
+ w_as_instruction_without_parameters ("cqo");
+ w_as_opcode (intel_asm ? "idiv" : "idivq");
+ }
+
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -3489,17 +3519,23 @@ static void w_as_instructions (register struct instruction *instruction)
w_as_dyadic_instruction (instruction,intel_asm ? "imul" : "imulq");
break;
case IDIV:
- w_as_div_instruction (instruction);
+ w_as_div_instruction (instruction,0);
break;
case IDIVI:
w_as_div_rem_i_instruction (instruction,0);
break;
+ case IDIVU:
+ w_as_div_instruction (instruction,1);
+ break;
case IREM:
- w_as_rem_instruction (instruction);
+ w_as_rem_instruction (instruction,0);
break;
case IREMI:
w_as_div_rem_i_instruction (instruction,1);
break;
+ case IREMU:
+ w_as_rem_instruction (instruction,1);
+ break;
case IAND:
w_as_dyadic_instruction (instruction,intel_asm ? "and" : "andq");
break;
diff --git a/cgiwas.c b/cgiwas.c
index dfebec4..fd9626a 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -1930,12 +1930,12 @@ static void w_as_div_instruction (struct instruction *instruction,int unsigned_d
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_div==0){
int i,log2i;
i=instruction->instruction_parameters[0].parameter_data.i;
- if (unsigned_div==0 && (i & (i-1))==0 && i>0){
+ if ((i & (i-1))==0 && i>0){
if (i==1)
return;