summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgias.c51
-rw-r--r--cgiwas.c81
2 files changed, 124 insertions, 8 deletions
diff --git a/cgias.c b/cgias.c
index 91fdb58..456c37d 100644
--- a/cgias.c
+++ b/cgias.c
@@ -1910,6 +1910,57 @@ static void as_div_instruction (struct instruction *instruction)
d_reg=instruction->instruction_parameters[1].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 (! ((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,REGISTER_O0);
+
+ if (log2i==1){
+ /* sar */
+ store_c (0301);
+ store_c (0300 | (7<<3) | reg_num (REGISTER_O0));
+ store_c (31);
+
+ as_r_r (0053,REGISTER_O0,d_reg); /* sub */
+ } else {
+ /* sar */
+ store_c (0301);
+ store_c (0300 | (7<<3) | reg_num (d_reg));
+ store_c (31);
+
+ /* and */
+ if (d_reg==EAX)
+ store_c (045);
+ else
+ as_r (0201,040,d_reg);
+ store_l ((1<<log2i)-1);
+
+ as_r_r (0003,REGISTER_O0,d_reg); /* add */
+ }
+
+ store_c (0301);
+ store_c (0300 | (7<<3) | reg_num (d_reg));
+ store_c (log2i);
+
+ return;
+ }
+
switch (d_reg){
case REGISTER_D0:
as_move_r_r (REGISTER_A1,REGISTER_O0);
diff --git a/cgiwas.c b/cgiwas.c
index 801b9b4..24cb953 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -1507,6 +1507,71 @@ static void w_as_div_instruction (struct instruction *instruction)
d_reg=instruction->instruction_parameters[1].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 (! ((i & (i-1))==0 && i>0)){
+ internal_error_in_function ("w_as_div_instruction");
+ return;
+ }
+
+ if (i==1)
+ return;
+
+ log2i=0;
+ while (i>1){
+ i=i>>1;
+ ++log2i;
+ }
+
+ w_as_opcode_movl();
+ w_as_register_register_newline (d_reg,REGISTER_O0);
+
+ if (log2i==1){
+ w_as_opcode ("sar");
+ if (intel_asm)
+ w_as_register_comma (REGISTER_O0);
+ w_as_immediate (31);
+ if (!intel_asm)
+ w_as_comma_register (REGISTER_O0);
+ w_as_newline();
+
+ w_as_opcode ("sub");
+ w_as_register_register_newline (REGISTER_O0,d_reg);
+ } else {
+ w_as_opcode ("sar");
+ if (intel_asm)
+ w_as_register_comma (d_reg);
+ w_as_immediate (31);
+ if (!intel_asm)
+ w_as_comma_register (d_reg);
+ w_as_newline();
+
+ w_as_opcode ("and");
+ if (intel_asm)
+ w_as_register_comma (d_reg);
+ w_as_immediate ((1<<log2i)-1);
+ if (!intel_asm)
+ w_as_comma_register (d_reg);
+ w_as_newline();
+
+ w_as_opcode ("add");
+ w_as_register_register_newline (REGISTER_O0,d_reg);
+ }
+
+ w_as_opcode ("sar");
+ if (intel_asm)
+ w_as_register_comma (d_reg);
+ w_as_immediate (log2i);
+ if (!intel_asm)
+ w_as_comma_register (d_reg);
+ w_as_newline();
+
+ return;
+ }
+
switch (d_reg){
case REGISTER_D0:
w_as_opcode_movl();
@@ -1524,10 +1589,10 @@ static void w_as_div_instruction (struct instruction *instruction)
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_indirect (instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
}
w_as_newline();
@@ -1651,10 +1716,10 @@ static void w_as_mod_instruction (struct instruction *instruction)
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_indirect (instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
+ } else
+ w_as_parameter (&instruction->instruction_parameters[0]);
}
w_as_newline();