00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include "system.h"
00026 #include "rtl.h"
00027 #include "function.h"
00028 #include "output.h"
00029 #include "tree.h"
00030 #include "expr.h"
00031 #include "regs.h"
00032 #include "flags.h"
00033 #include "hard-reg-set.h"
00034 #include "tm_p.h"
00035 #include "target.h"
00036 #include "target-def.h"
00037
00038 extern const char *reg_names[];
00039 rtx cmp_op0=0, cmp_op1=0;
00040
00041
00042 static const char *const cmp_tab[] = {
00043 "gt", "gt", "eq", "eq", "ge", "ge", "lt", "lt", "ne", "ne",
00044 "le", "le" };
00045
00046 static bool elxsi_assemble_integer PARAMS ((rtx, unsigned int, int));
00047 static void elxsi_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
00048 static void elxsi_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
00049
00050
00051 #undef TARGET_ASM_BYTE_OP
00052 #define TARGET_ASM_BYTE_OP NULL
00053 #undef TARGET_ASM_ALIGNED_HI_OP
00054 #define TARGET_ASM_ALIGNED_HI_OP NULL
00055 #undef TARGET_ASM_ALIGNED_SI_OP
00056 #define TARGET_ASM_ALIGNED_SI_OP NULL
00057 #undef TARGET_ASM_INTEGER
00058 #define TARGET_ASM_INTEGER elxsi_assemble_integer
00059
00060 #undef TARGET_ASM_FUNCTION_PROLOGUE
00061 #define TARGET_ASM_FUNCTION_PROLOGUE elxsi_output_function_prologue
00062 #undef TARGET_ASM_FUNCTION_EPILOGUE
00063 #define TARGET_ASM_FUNCTION_EPILOGUE elxsi_output_function_epilogue
00064
00065 struct gcc_target targetm = TARGET_INITIALIZER;
00066
00067
00068
00069
00070
00071 static bool
00072 elxsi_assemble_integer (x, size, aligned_p)
00073 rtx x;
00074 unsigned int size;
00075 int aligned_p;
00076 {
00077 if (aligned_p)
00078 switch (size)
00079 {
00080 case 1:
00081 case 2:
00082 case 4:
00083 fputs ("\t.data\t", asm_out_file);
00084 output_addr_const (asm_out_file, x);
00085 fprintf (asm_out_file, "{%d}\n", size * BITS_PER_UNIT);
00086 return true;
00087 }
00088 return default_assemble_integer (x, size, aligned_p);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 static void
00101 elxsi_output_function_prologue (file, size)
00102 FILE *file;
00103 HOST_WIDE_INT size;
00104 {
00105 register int regno;
00106 register int cnt = 0;
00107
00108
00109
00110 if (frame_pointer_needed)
00111 regs_ever_live[14] = 1, call_used_regs[14] = 0;
00112
00113 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00114 if (regs_ever_live[regno] && !call_used_regs[regno])
00115 cnt += 8;
00116
00117 if (size + cnt)
00118 fprintf (file, "\tadd.64\t.sp,=%d\n", -size - cnt);
00119
00120 cnt = 0;
00121 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00122 if (regs_ever_live[regno] && !call_used_regs[regno])
00123 fprintf (file, "\tst.64\t.r%d,[.sp]%d\n", regno, (cnt += 8) - 12);
00124
00125 if (frame_pointer_needed)
00126 fprintf (file, "\tadd.64\t.r14,.sp,=%d\n", size + cnt);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 static void
00138 elxsi_output_function_epilogue (file, size)
00139 FILE *file;
00140 HOST_WIDE_INT size;
00141 {
00142 register int regno;
00143 register int cnt = 0;
00144
00145
00146
00147
00148
00149 if (current_function_calls_alloca || size >= (256 - 8 * 10))
00150 {
00151
00152 fprintf (file, "\tld.64\t.r4,.r14\n");
00153
00154 for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
00155 if (regs_ever_live[regno] && !call_used_regs[regno])
00156 cnt += 8;
00157
00158 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
00159 if (regs_ever_live[regno] && !call_used_regs[regno])
00160 fprintf (file, "\tld.64\t.r%d,[.r14]%d\n", regno,
00161 -((cnt -= 8) + 8) - 4 - size);
00162
00163 fprintf (file, "\tld.64\t.sp,.r4\n\texit\t0\n");
00164 }
00165 else
00166 {
00167 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
00168 if (regs_ever_live[regno] && !call_used_regs[regno])
00169 fprintf (file, "\tld.64\t.r%d,[.sp]%d\n", regno, (cnt += 8) - 12);
00170
00171 fprintf (file, "\texit\t%d\n", size + cnt);
00172 }
00173 }
00174
00175
00176
00177 const char *
00178 cmp_jmp (s, type, where)
00179 const char *s;
00180 int type;
00181 rtx where;
00182 {
00183 rtx br_ops[3];
00184 char template[50];
00185 const char *f = "";
00186 const char *bits = "64";
00187 if (GET_MODE (cmp_op0) == SFmode) f = "f", bits = "32";
00188 if (GET_MODE (cmp_op0) == DFmode) f = "f";
00189 br_ops[0] = where;
00190 br_ops[1] = cmp_op0;
00191 br_ops[2] = cmp_op1;
00192 if (cmp_op1)
00193 sprintf(template, "%scmp%s.br.%s\t%%1,%%2:j%s\t%%l0",
00194 f, s, bits, cmp_tab[type]);
00195 else if (*f)
00196 sprintf(template, "fcmp.br.%s\t%%1,=0:j%s\t%%l0",
00197 bits, cmp_tab[type]);
00198 else if (*s)
00199 sprintf(template, "cmpu.br.64\t%%1,=0:j%s\t%%l0", s);
00200 else
00201 sprintf(template, "jmp.%s\t%%1,%%l0", cmp_tab[type+1]);
00202 output_asm_insn(template, br_ops);
00203 return "";
00204 }
00205
00206 const char *
00207 cmp_set (s, type, reg)
00208 const char *s, *type;
00209 rtx reg;
00210 {
00211 rtx br_ops[3];
00212 char template[50];
00213 const char *f = "";
00214 const char *bits = "64";
00215 if (GET_MODE (cmp_op0) == SFmode) f = "f", bits = "32";
00216 else if (GET_MODE (cmp_op0) == DFmode) f = "f";
00217 else if (GET_MODE (cmp_op0) == SImode) bits = "32";
00218 else if (GET_MODE (cmp_op0) == HImode) bits = "16";
00219 else if (GET_MODE (cmp_op0) == QImode) bits = "8";
00220 br_ops[0] = reg;
00221 br_ops[1] = cmp_op0;
00222 br_ops[2] = cmp_op1;
00223 if (cmp_op1)
00224 sprintf(template, "%scmp%s.%s\t%%0,%%1,%%2:%s",
00225 f, s, bits, type);
00226 else
00227 sprintf(template, "%scmp%s.%s\t%%0,%%1,=0:%s",
00228 f, s, bits, type);
00229 output_asm_insn(template, br_ops);
00230 return "";
00231 }
00232
00233 void
00234 print_operand_address (file, addr)
00235 FILE *file;
00236 register rtx addr;
00237 {
00238 register rtx reg1, reg2, breg, ireg;
00239 rtx offset;
00240
00241 switch (GET_CODE (addr))
00242 {
00243
00244 case MEM:
00245 if (GET_CODE (XEXP (addr, 0)) == REG)
00246 fprintf (file, "%s", reg_names[REGNO (addr)]);
00247 else abort();
00248 break;
00249
00250 case REG:
00251 fprintf (file, "[%s]", reg_names[REGNO (addr)]);
00252 break;
00253
00254 case PLUS:
00255 reg1 = 0; reg2 = 0;
00256 ireg = 0; breg = 0;
00257 offset = 0;
00258 if (GET_CODE (XEXP (addr, 0)) == REG)
00259 {
00260 offset = XEXP (addr, 1);
00261 addr = XEXP (addr, 0);
00262 }
00263 else if (GET_CODE (XEXP (addr, 1)) == REG)
00264 {
00265 offset = XEXP (addr, 0);
00266 addr = XEXP (addr, 1);
00267 }
00268 fprintf (file, "[%s]", reg_names[REGNO (addr)]);
00269 output_address (offset);
00270 break;
00271
00272 default:
00273 output_addr_const (file, addr);
00274 }
00275 }