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 "insn-config.h"
00027 #include "rtl.h"
00028 #include "function.h"
00029 #include "real.h"
00030 #include "recog.h"
00031 #include "output.h"
00032 #include "regs.h"
00033 #include "tree.h"
00034 #include "expr.h"
00035 #include "hard-reg-set.h"
00036 #include "tm_p.h"
00037 #include "target.h"
00038 #include "target-def.h"
00039
00040 static void we32k_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
00041 static void we32k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
00042
00043
00044 #undef TARGET_ASM_ALIGNED_HI_OP
00045 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
00046 #undef TARGET_ASM_ALIGNED_SI_OP
00047 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
00048
00049 #undef TARGET_ASM_FUNCTION_PROLOGUE
00050 #define TARGET_ASM_FUNCTION_PROLOGUE we32k_output_function_prologue
00051 #undef TARGET_ASM_FUNCTION_EPILOGUE
00052 #define TARGET_ASM_FUNCTION_EPILOGUE we32k_output_function_epilogue
00053
00054 struct gcc_target targetm = TARGET_INITIALIZER;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 static void
00066 we32k_output_function_prologue (file, size)
00067 FILE *file;
00068 HOST_WIDE_INT size;
00069 {
00070 register int nregs_to_save;
00071 register int regno;
00072
00073 nregs_to_save = 0;
00074 for (regno = 8; regno > 2; regno--)
00075 if (regs_ever_live[regno] && ! call_used_regs[regno])
00076 nregs_to_save = (9 - regno);
00077
00078 fprintf (file, "\tsave &%d\n", nregs_to_save);
00079 if (size)
00080 fprintf (file, "\taddw2 &%d,%%sp\n", (size + 3) & ~3);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 static void
00092 we32k_output_function_epilogue (file, size)
00093 FILE *file;
00094 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
00095 {
00096 register int nregs_to_restore;
00097 register int regno;
00098
00099 nregs_to_restore = 0;
00100 for (regno = 8; regno > 2; regno--)
00101 if (regs_ever_live[regno] && ! call_used_regs[regno])
00102 nregs_to_restore = (9 - regno);
00103
00104 fprintf (file, "\tret &%d\n", nregs_to_restore);
00105 }
00106
00107 void
00108 output_move_double (operands)
00109 rtx *operands;
00110 {
00111 rtx lsw_operands[2];
00112 rtx lsw_sreg = NULL;
00113 rtx msw_dreg = NULL;
00114
00115 if (GET_CODE (operands[0]) == REG)
00116 {
00117 lsw_operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
00118 msw_dreg = operands[0];
00119 }
00120 else if (GET_CODE (operands[0]) == MEM && offsettable_memref_p (operands[0]))
00121 lsw_operands[0] = adjust_address (operands[0], SImode, 4);
00122 else
00123 abort ();
00124
00125 if (GET_CODE (operands[1]) == REG)
00126 {
00127 lsw_operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
00128 lsw_sreg = lsw_operands[1];
00129 }
00130 else if (GET_CODE (operands[1]) == MEM && offsettable_memref_p (operands[1]))
00131 {
00132 lsw_operands[1] = adjust_address (operands[1], SImode, 4);
00133 lsw_sreg = operands[1];
00134 for ( ; ; )
00135 {
00136 if (REG_P (lsw_sreg))
00137 break;
00138 if (CONSTANT_ADDRESS_P (lsw_sreg))
00139 {
00140 lsw_sreg = NULL;
00141 break;
00142 }
00143 if (GET_CODE (lsw_sreg) == MEM)
00144 {
00145 lsw_sreg = XEXP (lsw_sreg, 0);
00146 continue;
00147 }
00148 if (GET_CODE (lsw_sreg) == PLUS)
00149 {
00150 if (CONSTANT_ADDRESS_P (XEXP (lsw_sreg, 1)))
00151 {
00152 lsw_sreg = XEXP (lsw_sreg, 0);
00153 continue;
00154 }
00155 else if (CONSTANT_ADDRESS_P (XEXP (lsw_sreg, 0)))
00156 {
00157 lsw_sreg = XEXP (lsw_sreg, 1);
00158 continue;
00159 }
00160 }
00161 abort ();
00162 }
00163 }
00164 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
00165 {
00166 lsw_operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
00167 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
00168 }
00169 else if (GET_CODE (operands[1]) == CONST_INT)
00170 {
00171 lsw_operands[1] = operands[1];
00172 operands[1] = const0_rtx;
00173 }
00174 else
00175 abort ();
00176
00177 if (!msw_dreg || !lsw_sreg || REGNO (msw_dreg) != REGNO (lsw_sreg))
00178 {
00179 output_asm_insn ("movw %1, %0", operands);
00180 output_asm_insn ("movw %1, %0", lsw_operands);
00181 }
00182 else
00183 {
00184 output_asm_insn ("movw %1, %0", lsw_operands);
00185 output_asm_insn ("movw %1, %0", operands);
00186 }
00187 }
00188
00189 void
00190 output_push_double (operands)
00191 rtx *operands;
00192 {
00193 rtx lsw_operands[1];
00194
00195 if (GET_CODE (operands[0]) == REG)
00196 lsw_operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
00197 else if (GET_CODE (operands[0]) == MEM && offsettable_memref_p (operands[0]))
00198 lsw_operands[0] = adjust_address (operands[0], SImode, 4);
00199 else if (GET_CODE (operands[0]) == CONST_DOUBLE)
00200 {
00201 lsw_operands[0] = GEN_INT (CONST_DOUBLE_HIGH (operands[0]));
00202 operands[0] = GEN_INT (CONST_DOUBLE_LOW (operands[0]));
00203 }
00204 else if (GET_CODE (operands[0]) == CONST_INT)
00205 {
00206 lsw_operands[0] = operands[0];
00207 operands[0] = const0_rtx;
00208 }
00209 else
00210 abort ();
00211
00212 output_asm_insn ("pushw %0", operands);
00213 output_asm_insn ("pushw %0", lsw_operands);
00214 }