summaryrefslogtreecommitdiff
path: root/cgaas.c
diff options
context:
space:
mode:
Diffstat (limited to 'cgaas.c')
-rw-r--r--cgaas.c217
1 files changed, 208 insertions, 9 deletions
diff --git a/cgaas.c b/cgaas.c
index 5e9bb02..11ba458 100644
--- a/cgaas.c
+++ b/cgaas.c
@@ -1718,7 +1718,7 @@ static void as_moveb_instruction (struct instruction *instruction)
internal_error_in_function ("as_moveb_instruction");
}
-static void as_movew_instruction (struct instruction *instruction)
+static void as_movedb_instruction (struct instruction *instruction)
{
switch (instruction->instruction_parameters[1].parameter_type){
case P_REGISTER:
@@ -1763,10 +1763,135 @@ static void as_movew_instruction (struct instruction *instruction)
break;
}
}
- internal_error_in_function ("as_movew_instruction");
+ internal_error_in_function ("as_movedb_instruction");
}
-static void as_movesw_instruction (struct instruction *instruction)
+static void as_moveqb_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[1].parameter_type){
+ case P_REGISTER:
+ {
+ int reg;
+
+ reg=instruction->instruction_parameters[1].parameter_data.reg.r;
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_REGISTER:
+ as_br_br (0213,instruction->instruction_parameters[0].parameter_data.reg.r,reg);
+ return;
+ case P_IMMEDIATE:
+ {
+ int reg_n;
+
+ reg_n=reg_num (reg);
+ if (reg_n>=4)
+ store_c (0x40 | ((reg_n & 8)>>3));
+ store_c (0270 | (reg_n & 7));
+ store_l (instruction->instruction_parameters[0].parameter_data.i);
+ return;
+ }
+ }
+
+ break;
+ }
+ case P_INDIRECT:
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_IMMEDIATE:
+ {
+ int reg1,reg1_n,offset;
+
+ offset=instruction->instruction_parameters[1].parameter_offset;
+ reg1=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ reg1_n=reg_num (reg1);
+
+ if (reg1_n & 8)
+ store_c (0x41);
+ store_c (0307);
+ if ((reg1_n & 7)==4/*RSP or R12*/){
+ if (offset==0){
+ store_c (0x04);
+ store_c (0044);
+ } else if (((signed char)offset)==offset){
+ store_c (0x44);
+ store_c (0044);
+ store_c (offset);
+ } else {
+ store_c (0x84);
+ store_c (0044);
+ store_l (offset);
+ }
+ } else {
+ if (offset==0 && (reg1_n & 7)!=5/*RBP or R13*/){
+ store_c (reg1_n & 7);
+ } else if (((signed char)offset)==offset){
+ store_c (0x40 | (reg1_n & 7));
+ store_c (offset);
+ } else {
+ store_c (0x80 | (reg1_n & 7));
+ store_l (offset);
+ }
+ }
+ store_l (instruction->instruction_parameters[0].parameter_data.i);
+ return;
+ }
+ case P_REGISTER:
+ as_br_id (0211,instruction->instruction_parameters[0].parameter_data.reg.r,
+ instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ }
+ break;
+ case P_INDEXED:
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_IMMEDIATE:
+ {
+ int reg1,reg2,reg1_n,reg2_n,shift,offset,x;
+
+ offset=instruction->instruction_parameters[1].parameter_offset;
+ reg1=instruction->instruction_parameters[1].parameter_data.ir->a_reg.r;
+ reg2=instruction->instruction_parameters[1].parameter_data.ir->d_reg.r;
+
+ reg1_n=reg_num (reg1);
+ reg2_n=reg_num (reg2);
+
+ shift=offset & 3;
+ offset=offset>>2;
+
+ if (reg2==ESP)
+ internal_error_in_function ("as_moveqb_instruction");
+
+ if (((reg1_n | reg2_n) & 8)!=0)
+ store_c (0x40 | ((reg2_n & 8)>>2) | ((reg1_n & 8)>>3));
+ store_c (0307);
+ x=(shift<<6) | ((reg2_n & 7)<<3) | (reg1_n & 7);
+ if (offset==0 && (reg1_n & 7)!=5/*RBP or R13*/){
+ store_c (0x04);
+ store_c (x);
+ } else if (((signed char)offset)==offset){
+ store_c (0x44);
+ store_c (x);
+ store_c (offset);
+ } else {
+ store_c (0x84);
+ store_c (x);
+ store_l (offset);
+ }
+ store_l (instruction->instruction_parameters[0].parameter_data.i);
+
+ return;
+ }
+ case P_REGISTER:
+ as_br_x (0211,instruction->instruction_parameters[0].parameter_data.reg.r,
+ instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.ir);
+ return;
+ }
+ break;
+ }
+ internal_error_in_function ("as_moveqb_instruction");
+}
+
+static void as_loadsqb_instruction (struct instruction *instruction)
{
switch (instruction->instruction_parameters[1].parameter_type){
case P_REGISTER:
@@ -1788,7 +1913,7 @@ static void as_movesw_instruction (struct instruction *instruction)
break;
}
}
- internal_error_in_function ("as_movesw_instruction");
+ internal_error_in_function ("as_loadsqb_instruction");
}
static void as_lea_instruction (struct instruction *instruction)
@@ -3464,6 +3589,11 @@ static void as_f_i (int code1,int code2,DOUBLE *r_p,int d_freg)
new_label->label_flags=DATA_LABEL;
+#ifdef FUNCTION_LEVEL_LINKING
+ if (data_object_label==NULL)
+ as_new_data_module();
+#endif
+
if (data_object_label->object_section_align<3)
data_object_label->object_section_align=3;
if ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 4)
@@ -3520,6 +3650,53 @@ static void as_fmove_instruction (struct instruction *instruction)
internal_error_in_function ("as_fmove_instruction");
}
+static void as_floads_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[1].parameter_type){
+ case P_F_REGISTER:
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_INDIRECT:
+ /* cvtss2sd */
+ as_f_id (0xf3,0x5a,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.reg.r,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ case P_INDEXED:
+ /* cvtss2sd */
+ as_f_x (0xf3,0x5a,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.ir,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ }
+ break;
+ }
+ internal_error_in_function ("as_floads_instruction");
+}
+
+static void as_fmoves_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[1].parameter_type){
+ case P_INDIRECT:
+ if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ /* movss */
+ as_f_id (0xf3,0x11,instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.reg.r,
+ instruction->instruction_parameters[0].parameter_data.reg.r);
+ return;
+ }
+ break;
+ case P_INDEXED:
+ if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ /* movsd */
+ as_f_x (0xf3,0x11,instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.ir,
+ instruction->instruction_parameters[0].parameter_data.reg.r);
+ return;
+ }
+ }
+ internal_error_in_function ("as_fmoves_instruction");
+}
+
static void as_dyadic_float_instruction (struct instruction *instruction,int code1,int code2)
{
int d_freg;
@@ -3583,6 +3760,11 @@ static void as_float_neg_instruction (struct instruction *instruction)
new_label->label_flags=DATA_LABEL;
+#ifdef FUNCTION_LEVEL_LINKING
+ if (data_object_label==NULL)
+ as_new_data_module();
+#endif
+
if (data_object_label->object_section_align<4)
data_object_label->object_section_align=4;
while ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 0xc)
@@ -3636,6 +3818,11 @@ static void as_float_abs_instruction (struct instruction *instruction)
new_label->label_flags=DATA_LABEL;
+#ifdef FUNCTION_LEVEL_LINKING
+ if (data_object_label==NULL)
+ as_new_data_module();
+#endif
+
if (data_object_label->object_section_align<4)
data_object_label->object_section_align=4;
while ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 0xc)
@@ -4121,15 +4308,18 @@ static void as_instructions (struct instruction *instruction)
case IBTST:
as_btst_instruction (instruction);
break;
- case IMOVEW:
- as_movew_instruction (instruction);
- break;
- case IMOVESW:
- as_movesw_instruction (instruction);
+ case ILOADSQB:
+ as_loadsqb_instruction (instruction);
break;
case IMOVEB:
as_moveb_instruction (instruction);
break;
+ case IMOVEDB:
+ as_movedb_instruction (instruction);
+ break;
+ case IMOVEQB:
+ as_moveqb_instruction (instruction);
+ break;
case IEXG:
as_exg_instruction (instruction);
break;
@@ -4220,6 +4410,15 @@ static void as_instructions (struct instruction *instruction)
case IFSNE:
as_set_float_condition_instruction (instruction,3);
break;
+ case IFLOADS:
+ as_floads_instruction (instruction);
+ break;
+ case IFCVT2S:
+ as_dyadic_float_instruction (instruction,0xf2,0x5a); /* cvtsd2ss */
+ break;
+ case IFMOVES:
+ as_fmoves_instruction (instruction);
+ break;
case IRTSI:
as_rtsi_instruction (instruction);
break;