summaryrefslogtreecommitdiff
path: root/cgiwas.c
diff options
context:
space:
mode:
authorJohn van Groningen2011-12-01 12:32:08 +0000
committerJohn van Groningen2011-12-01 12:32:08 +0000
commit41440a54ab504b678244a5174bdc4e34a5d4c2c6 (patch)
treefc2a4829e6b3e0e32b33c98cad01369c7029962c /cgiwas.c
parentgenerate thread safe code on 32 bit windows if THREAD32 is defined (diff)
implement mulUUL for 32 bit thread safe code
Diffstat (limited to 'cgiwas.c')
-rw-r--r--cgiwas.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/cgiwas.c b/cgiwas.c
index 3248c76..a021ed8 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -2901,14 +2901,85 @@ 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;
+#ifdef THREAD32
+ int reg_3;
+#endif
reg_1=instruction->instruction_parameters[0].parameter_data.reg.r;
reg_2=instruction->instruction_parameters[1].parameter_data.reg.r;
+#ifdef THREAD32
+ reg_3=instruction->instruction_parameters[2].parameter_data.reg.r;
+
+ if (reg_3==REGISTER_D0){
+ if (reg_1==REGISTER_A1){
+ w_as_movl_register_register_newline (reg_2,REGISTER_D0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_movl_register_register_newline (REGISTER_D0,reg_2);
+ } else if (reg_2==REGISTER_A1){
+ w_as_movl_register_register_newline (reg_2,REGISTER_D0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_2movl_registers (REGISTER_D0,REGISTER_A1,reg_1);
+ } else {
+ w_as_2movl_registers (REGISTER_A1,reg_2,REGISTER_D0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_3movl_registers (REGISTER_D0,reg_2,REGISTER_A1,reg_1);
+ }
+ return;
+ }
+
+ if (reg_3==REGISTER_A1){
+ if (reg_2==REGISTER_D0){
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_movl_register_register_newline (REGISTER_A1,reg_1);
+ } else if (reg_1==REGISTER_D0){
+ w_as_opcode_register_newline ("mul",reg_2);
+ w_as_2movl_registers (REGISTER_A1,REGISTER_D0,reg_2);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0);
+ w_as_movl_register_register_newline (REGISTER_A1,reg_1);
+ }
+ return;
+ }
+
+ if (reg_2==REGISTER_D0){
+ if (reg_1==REGISTER_A1){
+ w_as_opcode_register_newline ("mul",reg_1);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,reg_3);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_2movl_registers (reg_3,REGISTER_A1,reg_1);
+ }
+ } else if (reg_1==REGISTER_A1){
+ w_as_2movl_registers (reg_2,REGISTER_D0,reg_3);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_2movl_registers (reg_3,REGISTER_D0,reg_2);
+ } else if (reg_1==REGISTER_D0){
+ if (reg_2==REGISTER_A1){
+ w_as_opcode_register_newline ("mul",REGISTER_A1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,reg_3);
+ w_as_opcode_register_newline ("mul",reg_2);
+ w_as_3movl_registers (reg_3,REGISTER_A1,REGISTER_D0,reg_2);
+ }
+ } else if (reg_2==REGISTER_A1){
+ w_as_2movl_registers (reg_2,REGISTER_D0,reg_3);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_3movl_registers (reg_3,REGISTER_D0,REGISTER_A1,reg_1);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0);
+ w_as_movl_register_register_newline (REGISTER_A1,reg_3);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0);
+ w_as_2movl_registers (reg_3,REGISTER_A1,reg_1);
+ }
+#else
if (reg_2==REGISTER_D0){
if (reg_1==REGISTER_A1){
w_as_opcode_register_newline ("mul",reg_1);
@@ -2941,8 +3012,10 @@ static void w_as_mulud_instruction (struct instruction *instruction)
w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0);
w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_1);
}
+#endif
}
+#ifndef THREAD32
static void w_as_divdu_instruction (struct instruction *instruction)
{
int reg_1,reg_2,reg_3;
@@ -4762,10 +4835,10 @@ 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;
+#ifndef THREAD32
case IDIVDU:
w_as_divdu_instruction (instruction);
break;