summaryrefslogtreecommitdiff
path: root/cgsas.c
diff options
context:
space:
mode:
authorJohn van Groningen2004-07-15 14:07:47 +0000
committerJohn van Groningen2004-07-15 14:07:47 +0000
commit81b977fad46f1ca2221de399f247cdc9cd85f717 (patch)
treea5338bde520aab5ff64cdfdd9b51d0da4d24777d /cgsas.c
parentadd absR and negI for sparc (diff)
add absR and negI for sparc, commit not yet used code for new array representation
Diffstat (limited to 'cgsas.c')
-rw-r--r--cgsas.c240
1 files changed, 182 insertions, 58 deletions
diff --git a/cgsas.c b/cgsas.c
index 3adfcf4..d18d618 100644
--- a/cgsas.c
+++ b/cgsas.c
@@ -12,6 +12,7 @@
#include <elf.h>
#define ELF
+#undef ALIGN_REAL_ARRAYS
#include "cgport.h"
#include "cgrconst.h"
@@ -21,6 +22,12 @@
#include "cgcode.h"
#include "cgswas.h"
+#ifdef ALIGN_REAL_ARRAYS
+# define LOAD_STORE_ALIGNED_REAL 4
+#endif
+
+#define FUNCTION_LEVEL_LINKING
+
#define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n)
#define U4(s,v1,v2,v3,v4) s->v1;s->v2;s->v3;s->v4
@@ -556,7 +563,7 @@ static unsigned char real_reg_num [32] =
#define as_i_abd3(ra,rb,rd,op) store_instruction(0xc0000000|((op)<<19)|(reg_num(rd)<<25)|(reg_num(ra)<<14)|reg_num(rb))
#define as_i_aod3(ra,o,rd,op) store_instruction(0xc0000000|((op)<<19)|(reg_num(rd)<<25)|(reg_num(ra)<<14)|0x2000|((o)&0x1fff))
#define as_i_foa3(fa,o,ra,op) store_instruction(0xc0000000|((op)<<19)|((fa)<<25)|((reg_num(ra))<<14)|0x2000|((o)&0x1fff))
-#define as_i_fab3(fa,ra,rb,op) store_instruction(0xc0000000|((op)<<19)|((fa)<<25)|((reg_num(ra))<<14)|(rb))
+#define as_i_fab3(fa,ra,rb,op) store_instruction(0xc0000000|((op)<<19)|((fa)<<25)|((reg_num(ra))<<14)|(reg_num(rb)))
#define LD_OP 0
#define LDUB_OP 1
@@ -570,6 +577,7 @@ static unsigned char real_reg_num [32] =
#define LDF_OP 0x20
#define LDDF_OP 0x23
#define STF_OP 0x24
+#define STDF_OP 0x27
#define AND_OP 1
#define OR_OP 2
@@ -617,6 +625,7 @@ static unsigned char real_reg_num [32] =
#define as_jmpli(i,ra,rd) as_i_aid2(ra,i,rd,0x38)
#define as_ld(o,ra,rd) as_i_aod3(ra,o,rd,LD_OP)
#define as_lddf(o,ra,fd) as_i_foa3(fd,o,ra,LDDF_OP)
+#define as_lddf_x(ra,rb,fd) as_i_fab3(fd,ra,rb,LDDF_OP)
#define as_ldf(o,ra,fd) as_i_foa3(fd,o,ra,LDF_OP)
#define as_ldf_x(ra,rb,fd) as_i_fab3(fd,ra,rb,LDF_OP)
#define as_ldsh(o,ra,rd) as_i_aod3(ra,o,rd,LDSH_OP)
@@ -624,11 +633,14 @@ static unsigned char real_reg_num [32] =
#define as_ld_x(ra,rb,rd) as_i_abd3(ra,rb,rd,LD_OP)
#define as_fmovs(fa,fd) as_i_ff2(fa,fd,0x34,1);
#define as_fnegs(fa,fd) as_i_ff2(fa,fd,0x34,5);
+#define as_fabss(fa,fd) as_i_ff2(fa,fd,0x34,9);
#define as_or(ra,rb,rd) as_i_abd2(ra,rb,rd,OR_OP)
#define as_orcc(ra,rb,rd) as_i_abd2(ra,rb,rd,0x12)
#define as_ori(ra,i,rd) as_i_aid2(ra,i,rd,OR_OP)
#define as_sethi(i,rd) as_i_id0(i,rd)
#define as_slli(ra,i,rd) as_i_aid2(ra,i,rd,SLL_OP)
+#define as_stdf(fa,o,rd) as_i_foa3(fa,o,rd,STDF_OP)
+#define as_stdf_x(fa,ra,rb) as_i_fab3(fa,ra,rb,STDF_OP)
#define as_stf(fa,o,rd) as_i_foa3(fa,o,rd,STF_OP)
#define as_sub(ra,rb,rd) as_i_abd2(ra,rb,rd,4)
#define as_subcc(ra,rb,rd) as_i_abd2(ra,rb,rd,0x14)
@@ -1294,6 +1306,11 @@ static void w_as_mul_or_div_instruction (struct instruction *instruction,struct
as_mov (REGISTER_O0,instruction->instruction_parameters[1].parameter_data.reg.r);
}
+static void as_neg_instruction (struct instruction *instruction)
+{
+ as_sub (REGISTER_G0,instruction->instruction_parameters[0].parameter_data.reg.r,instruction->instruction_parameters[0].parameter_data.reg.r);
+}
+
#ifndef FUNCTION_LEVEL_LINKING
static int data_section_alignment_mask;
#endif
@@ -1335,62 +1352,131 @@ static void as_load_float_immediate (double float_value,int fp_reg)
as_hi_or_lo_label (new_label,0,LO12_RELOCATION);
}
-static struct parameter as_float_parameter (struct parameter parameter)
+static void as_load_float_indirect (struct parameter *parameter_p,int f_reg)
+{
+#ifdef ALIGN_REAL_ARRAYS
+ if (parameter_p->parameter_flags & LOAD_STORE_ALIGNED_REAL)
+ as_lddf (parameter_p->parameter_offset,parameter_p->parameter_data.reg.r,f_reg<<1);
+ else {
+#endif
+ as_ldf (parameter_p->parameter_offset,parameter_p->parameter_data.reg.r,f_reg<<1);
+ as_ldf (parameter_p->parameter_offset+4,parameter_p->parameter_data.reg.r,(f_reg<<1)+1);
+#ifdef ALIGN_REAL_ARRAYS
+ }
+#endif
+}
+
+static void as_load_float_indexed (struct parameter *parameter_p,int f_reg)
+{
+ int offset;
+
+ offset=parameter_p->parameter_offset>>2;
+
+#ifdef ALIGN_REAL_ARRAYS
+ if (parameter_p->parameter_flags & LOAD_STORE_ALIGNED_REAL){
+ if (offset==0)
+ as_lddf_x (parameter_p->parameter_data.ir->a_reg.r,parameter_p->parameter_data.ir->d_reg.r,f_reg<<1);
+ else {
+ as_add (parameter_p->parameter_data.ir->a_reg.r,parameter_p->parameter_data.ir->d_reg.r,REGISTER_O0);
+ as_lddf (offset,REGISTER_O0,f_reg<<1);
+ }
+ } else {
+#endif
+ as_add (parameter_p->parameter_data.ir->a_reg.r,parameter_p->parameter_data.ir->d_reg.r,REGISTER_O0);
+ as_ldf (offset,REGISTER_O0,f_reg<<1);
+ as_ldf (offset+4,REGISTER_O0,(f_reg<<1)+1);
+#ifdef ALIGN_REAL_ARRAYS
+ }
+#endif
+}
+
+static int as_float_parameter (struct parameter parameter)
{
switch (parameter.parameter_type){
case P_F_IMMEDIATE:
as_load_float_immediate (*parameter.parameter_data.r,15);
-
- parameter.parameter_type=P_F_REGISTER;
- parameter.parameter_data.reg.r=15;
- break;
+ return 15;
case P_INDIRECT:
+#ifdef ALIGN_REAL_ARRAYS
+ if (parameter.parameter_flags & LOAD_STORE_ALIGNED_REAL)
+ as_lddf (parameter.parameter_offset,parameter.parameter_data.reg.r,30);
+ else {
+#endif
as_ldf (parameter.parameter_offset,parameter.parameter_data.reg.r,30);
as_ldf (parameter.parameter_offset+4,parameter.parameter_data.reg.r,31);
-
- parameter.parameter_type=P_F_REGISTER;
- parameter.parameter_data.reg.r=15;
- break;
+#ifdef ALIGN_REAL_ARRAYS
+ }
+#endif
+ return 15;
case P_INDEXED:
+ {
+ int offset;
+
+ offset=parameter.parameter_offset>>2;
+
+#ifdef ALIGN_REAL_ARRAYS
+ if (parameter.parameter_flags & LOAD_STORE_ALIGNED_REAL){
+ if (offset==0)
+ as_lddf_x (parameter.parameter_data.ir->a_reg.r,parameter.parameter_data.ir->d_reg.r,30);
+ else {
+ as_add (parameter.parameter_data.ir->a_reg.r,parameter.parameter_data.ir->d_reg.r,REGISTER_O0);
+
+ as_lddf (offset,REGISTER_O0,30);
+ }
+ } else {
+#endif
as_add (parameter.parameter_data.ir->a_reg.r,parameter.parameter_data.ir->d_reg.r,REGISTER_O0);
- as_ldf (parameter.parameter_offset>>2,REGISTER_O0,30);
- as_ldf ((parameter.parameter_offset>>2)+4,REGISTER_O0,31);
-
- parameter.parameter_type=P_F_REGISTER;
- parameter.parameter_data.reg.r=15;
- break;
+ as_ldf (offset,REGISTER_O0,30);
+ as_ldf (offset+4,REGISTER_O0,31);
+#ifdef ALIGN_REAL_ARRAYS
+ }
+#endif
+ return 15;
+ }
+ case P_F_REGISTER:
+ return parameter.parameter_data.reg.r;
}
- return parameter;
+ internal_error_in_function ("as_float_parameter");
+ return 0;
}
static void as_compare_float_instruction (struct instruction *instruction)
{
- struct parameter parameter_0;
+ int f_reg;
- parameter_0=as_float_parameter (instruction->instruction_parameters[0]);
+ f_reg=as_float_parameter (instruction->instruction_parameters[0]);
- as_fcmpd (instruction->instruction_parameters[1].parameter_data.reg.r<<1,parameter_0.parameter_data.reg.r<<1);
+ as_fcmpd (instruction->instruction_parameters[1].parameter_data.reg.r<<1,f_reg<<1);
}
static void as_sqrt_float_instruction (struct instruction *instruction)
{
- struct parameter parameter_0;
+ int f_reg;
- parameter_0=as_float_parameter (instruction->instruction_parameters[0]);
+ f_reg=as_float_parameter (instruction->instruction_parameters[0]);
- as_fsqrtd (parameter_0.parameter_data.reg.r<<1,instruction->instruction_parameters[1].parameter_data.reg.r<<1);
+ as_fsqrtd (f_reg<<1,instruction->instruction_parameters[1].parameter_data.reg.r<<1);
}
static void as_neg_float_instruction (struct instruction *instruction)
{
- struct parameter parameter_0;
int freg1,freg2;
- parameter_0=as_float_parameter (instruction->instruction_parameters[0]);
-
- freg1=parameter_0.parameter_data.reg.r;
freg2=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_INDIRECT:
+ as_load_float_indirect (&instruction->instruction_parameters[0],freg2);
+ freg1=freg2;
+ break;
+ case P_INDEXED:
+ as_load_float_indexed (&instruction->instruction_parameters[0],freg2);
+ freg1=freg2;
+ break;
+ default:
+ freg1=as_float_parameter (instruction->instruction_parameters[0]);
+ }
as_fnegs (freg1<<1,freg2<<1);
@@ -1398,14 +1484,38 @@ static void as_neg_float_instruction (struct instruction *instruction)
as_fmovs ((freg1<<1)+1,(freg2<<1)+1);
}
+static void as_abs_float_instruction (struct instruction *instruction)
+{
+ int freg1,freg2;
+
+ freg2=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_INDIRECT:
+ as_load_float_indirect (&instruction->instruction_parameters[0],freg2);
+ freg1=freg2;
+ break;
+ case P_INDEXED:
+ as_load_float_indexed (&instruction->instruction_parameters[0],freg2);
+ freg1=freg2;
+ break;
+ default:
+ freg1=as_float_parameter (instruction->instruction_parameters[0]);
+ }
+
+ as_fabss (freg1<<1,freg2<<1);
+
+ if (freg1!=freg2)
+ as_fmovs ((freg1<<1)+1,(freg2<<1)+1);
+}
+
static void as_tryadic_float_instruction (struct instruction *instruction,int opcode)
{
- struct parameter parameter_0;
+ int f_reg;
- parameter_0=as_float_parameter (instruction->instruction_parameters[0]);
+ f_reg=as_float_parameter (instruction->instruction_parameters[0]);
- as_i_fff2 (instruction->instruction_parameters[1].parameter_data.reg.r<<1,
- parameter_0.parameter_data.reg.r<<1,
+ as_i_fff2 (instruction->instruction_parameters[1].parameter_data.reg.r<<1,f_reg<<1,
instruction->instruction_parameters[1].parameter_data.reg.r<<1,
0x34,opcode);
}
@@ -1429,12 +1539,10 @@ static struct instruction *as_fmove_instruction (struct instruction *instruction
case IFADD: case IFSUB: case IFMUL: case IFDIV:
if (next_instruction->instruction_parameters[1].parameter_data.reg.r==reg1)
{
- struct parameter parameter_0;
int reg_s;
- parameter_0=as_float_parameter (next_instruction->instruction_parameters[0]);
+ reg_s=as_float_parameter (next_instruction->instruction_parameters[0]);
- reg_s=parameter_0.parameter_data.reg.r;
if (reg_s==reg1)
reg_s=reg0;
@@ -1463,25 +1571,10 @@ static struct instruction *as_fmove_instruction (struct instruction *instruction
return instruction;
}
case P_INDIRECT:
- as_ldf (instruction->instruction_parameters[0].parameter_offset,
- instruction->instruction_parameters[0].parameter_data.reg.r,
- instruction->instruction_parameters[1].parameter_data.reg.r<<1);
-
- as_ldf (instruction->instruction_parameters[0].parameter_offset+4,
- instruction->instruction_parameters[0].parameter_data.reg.r,
- (instruction->instruction_parameters[1].parameter_data.reg.r<<1)+1);
-
+ as_load_float_indirect (&instruction->instruction_parameters[0],instruction->instruction_parameters[1].parameter_data.reg.r);
return instruction;
case P_INDEXED:
- as_add (instruction->instruction_parameters[0].parameter_data.ir->a_reg.r,
- instruction->instruction_parameters[0].parameter_data.ir->d_reg.r,REGISTER_O0);
-
- as_ldf (instruction->instruction_parameters[0].parameter_offset>>2,REGISTER_O0,
- instruction->instruction_parameters[1].parameter_data.reg.r<<1);
-
- as_ldf ((instruction->instruction_parameters[0].parameter_offset>>2)+4,REGISTER_O0,
- (instruction->instruction_parameters[1].parameter_data.reg.r<<1)+1);
-
+ as_load_float_indexed (&instruction->instruction_parameters[0],instruction->instruction_parameters[1].parameter_data.reg.r);
return instruction;
case P_F_IMMEDIATE:
as_load_float_immediate (*instruction->instruction_parameters[0].parameter_data.r,instruction->instruction_parameters[1].parameter_data.reg.r);
@@ -1490,6 +1583,13 @@ static struct instruction *as_fmove_instruction (struct instruction *instruction
break;
case P_INDIRECT:
if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+#ifdef ALIGN_REAL_ARRAYS
+ if (instruction->instruction_parameters[1].parameter_flags & LOAD_STORE_ALIGNED_REAL){
+ as_stdf (instruction->instruction_parameters[0].parameter_data.reg.r<<1,
+ instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ } else {
+#endif
as_stf (instruction->instruction_parameters[0].parameter_data.reg.r<<1,
instruction->instruction_parameters[1].parameter_offset,
instruction->instruction_parameters[1].parameter_data.reg.r);
@@ -1497,21 +1597,39 @@ static struct instruction *as_fmove_instruction (struct instruction *instruction
as_stf ((instruction->instruction_parameters[0].parameter_data.reg.r<<1)+1,
instruction->instruction_parameters[1].parameter_offset+4,
instruction->instruction_parameters[1].parameter_data.reg.r);
-
+#ifdef ALIGN_REAL_ARRAYS
+ }
+#endif
return instruction;
}
break;
case P_INDEXED:
if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ int offset;
+
+ offset=instruction->instruction_parameters[1].parameter_offset>>2;
+#ifdef ALIGN_REAL_ARRAYS
+ if (instruction->instruction_parameters[1].parameter_flags & LOAD_STORE_ALIGNED_REAL){
+ if (offset==0)
+ as_stdf_x (instruction->instruction_parameters[0].parameter_data.reg.r<<1,
+ instruction->instruction_parameters[1].parameter_data.ir->a_reg.r,
+ instruction->instruction_parameters[1].parameter_data.ir->d_reg.r);
+ else {
+ as_add (instruction->instruction_parameters[1].parameter_data.ir->a_reg.r,
+ instruction->instruction_parameters[1].parameter_data.ir->d_reg.r,REGISTER_O0);
+
+ as_stdf (instruction->instruction_parameters[0].parameter_data.reg.r<<1,offset,REGISTER_O0);
+ }
+ } else {
+#endif
as_add (instruction->instruction_parameters[1].parameter_data.ir->a_reg.r,
instruction->instruction_parameters[1].parameter_data.ir->d_reg.r,REGISTER_O0);
- as_stf (instruction->instruction_parameters[0].parameter_data.reg.r<<1,
- instruction->instruction_parameters[1].parameter_offset>>2,REGISTER_O0);
-
- as_stf ((instruction->instruction_parameters[0].parameter_data.reg.r<<1)+1,
- (instruction->instruction_parameters[1].parameter_offset>>2)+4,REGISTER_O0);
-
+ as_stf (instruction->instruction_parameters[0].parameter_data.reg.r<<1,offset,REGISTER_O0);
+ as_stf ((instruction->instruction_parameters[0].parameter_data.reg.r<<1)+1,offset+4,REGISTER_O0);
+#ifdef ALIGN_REAL_ARRAYS
+ }
+#endif
return instruction;
}
}
@@ -1711,6 +1829,9 @@ static void as_instructions (register struct instruction *instruction)
case IMOVEB:
as_move_instruction (instruction,SIZE_BYTE);
break;
+ case INEG:
+ as_neg_instruction (instruction);
+ break;
case IFMOVE:
instruction=as_fmove_instruction (instruction);
break;
@@ -1760,6 +1881,9 @@ static void as_instructions (register struct instruction *instruction)
case IFNEG:
as_neg_float_instruction (instruction);
break;
+ case IFABS:
+ as_abs_float_instruction (instruction);
+ break;
case IFSEQ:
as_set_float_condition_instruction (instruction,FE_COND);
break;