00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define TCG_TARGET_HPPA 1
00026
00027 #if defined(_PA_RISC1_1)
00028 #define TCG_TARGET_REG_BITS 32
00029 #else
00030 #error unsupported
00031 #endif
00032
00033 #define TCG_TARGET_WORDS_BIGENDIAN
00034
00035 #define TCG_TARGET_NB_REGS 32
00036
00037 enum {
00038 TCG_REG_R0 = 0,
00039 TCG_REG_R1,
00040 TCG_REG_RP,
00041 TCG_REG_R3,
00042 TCG_REG_R4,
00043 TCG_REG_R5,
00044 TCG_REG_R6,
00045 TCG_REG_R7,
00046 TCG_REG_R8,
00047 TCG_REG_R9,
00048 TCG_REG_R10,
00049 TCG_REG_R11,
00050 TCG_REG_R12,
00051 TCG_REG_R13,
00052 TCG_REG_R14,
00053 TCG_REG_R15,
00054 TCG_REG_R16,
00055 TCG_REG_R17,
00056 TCG_REG_R18,
00057 TCG_REG_R19,
00058 TCG_REG_R20,
00059 TCG_REG_R21,
00060 TCG_REG_R22,
00061 TCG_REG_R23,
00062 TCG_REG_R24,
00063 TCG_REG_R25,
00064 TCG_REG_R26,
00065 TCG_REG_DP,
00066 TCG_REG_RET0,
00067 TCG_REG_RET1,
00068 TCG_REG_SP,
00069 TCG_REG_R31,
00070 };
00071
00072
00073 #define TCG_REG_CALL_STACK TCG_REG_SP
00074 #define TCG_TARGET_STACK_ALIGN 16
00075 #define TCG_TARGET_STACK_GROWSUP
00076
00077
00078
00079
00080
00081
00082
00083
00084 #define TCG_AREG0 TCG_REG_R17
00085 #define TCG_AREG1 TCG_REG_R14
00086 #define TCG_AREG2 TCG_REG_R15
00087 #define TCG_AREG3 TCG_REG_R16
00088
00089 static inline void flush_icache_range(unsigned long start, unsigned long stop)
00090 {
00091 start &= ~31;
00092 while (start <= stop)
00093 {
00094 asm volatile ("fdc 0(%0)\n"
00095 "sync\n"
00096 "fic 0(%%sr4, %0)\n"
00097 "sync\n"
00098 : : "r"(start) : "memory");
00099 start += 32;
00100 }
00101 }
00102
00103
00104 extern void *__canonicalize_funcptr_for_compare(void *);
00105
00106
00107 #define rnd(x) (((x)+0x1000)&~0x1fff)
00108
00109 #define lsel(v,a) (((v)+(a))>>11)
00110
00111 #define rsel(v,a) (((v)+(a))&0x7ff)
00112
00113 #define lrsel(v,a) (((v)+rnd(a))>>11)
00114
00115 #define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
00116
00117 #define mask(x,sz) ((x) & ~((1<<(sz))-1))
00118
00119 static inline int reassemble_12(int as12)
00120 {
00121 return (((as12 & 0x800) >> 11) |
00122 ((as12 & 0x400) >> 8) |
00123 ((as12 & 0x3ff) << 3));
00124 }
00125
00126 static inline int reassemble_14(int as14)
00127 {
00128 return (((as14 & 0x1fff) << 1) |
00129 ((as14 & 0x2000) >> 13));
00130 }
00131
00132 static inline int reassemble_17(int as17)
00133 {
00134 return (((as17 & 0x10000) >> 16) |
00135 ((as17 & 0x0f800) << 5) |
00136 ((as17 & 0x00400) >> 8) |
00137 ((as17 & 0x003ff) << 3));
00138 }
00139
00140 static inline int reassemble_21(int as21)
00141 {
00142 return (((as21 & 0x100000) >> 20) |
00143 ((as21 & 0x0ffe00) >> 8) |
00144 ((as21 & 0x000180) << 7) |
00145 ((as21 & 0x00007c) << 14) |
00146 ((as21 & 0x000003) << 12));
00147 }
00148
00149 static inline void hppa_patch21l(uint32_t *insn, int val, int addend)
00150 {
00151 val = lrsel(val, addend);
00152 *insn = mask(*insn, 21) | reassemble_21(val);
00153 }
00154
00155 static inline void hppa_patch14r(uint32_t *insn, int val, int addend)
00156 {
00157 val = rrsel(val, addend);
00158 *insn = mask(*insn, 14) | reassemble_14(val);
00159 }
00160
00161 static inline void hppa_patch17r(uint32_t *insn, int val, int addend)
00162 {
00163 val = rrsel(val, addend);
00164 *insn = (*insn & ~0x1f1ffd) | reassemble_17(val);
00165 }
00166
00167
00168 static inline void hppa_patch21l_dprel(uint32_t *insn, int val, int addend)
00169 {
00170 register unsigned int dp asm("r27");
00171 hppa_patch21l(insn, val - dp, addend);
00172 }
00173
00174 static inline void hppa_patch14r_dprel(uint32_t *insn, int val, int addend)
00175 {
00176 register unsigned int dp asm("r27");
00177 hppa_patch14r(insn, val - dp, addend);
00178 }
00179
00180 static inline void hppa_patch17f(uint32_t *insn, int val, int addend)
00181 {
00182 int dot = (int)insn & ~0x3;
00183 int v = ((val + addend) - dot - 8) / 4;
00184 if (v > (1 << 16) || v < -(1 << 16)) {
00185 printf("cannot fit branch to offset %d [%08x->%08x]\n", v, dot, val);
00186 abort();
00187 }
00188 *insn = (*insn & ~0x1f1ffd) | reassemble_17(v);
00189 }
00190
00191 static inline void hppa_load_imm21l(uint32_t *insn, int val, int addend)
00192 {
00193
00194 *insn = 0x20200000 | reassemble_21(lrsel(val, 0));
00195 }
00196
00197 static inline void hppa_load_imm14r(uint32_t *insn, int val, int addend)
00198 {
00199
00200 hppa_patch14r(insn, val, addend);
00201
00202 if (addend == 0)
00203 *insn = (*insn & ~0xfc000000) | (0x0d << 26);
00204 }