|
|
1.1 ! root 1: /* ! 2: * Tiny Code Generator for QEMU ! 3: * ! 4: * Copyright (c) 2008 Fabrice Bellard ! 5: * ! 6: * Permission is hereby granted, free of charge, to any person obtaining a copy ! 7: * of this software and associated documentation files (the "Software"), to deal ! 8: * in the Software without restriction, including without limitation the rights ! 9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ! 10: * copies of the Software, and to permit persons to whom the Software is ! 11: * furnished to do so, subject to the following conditions: ! 12: * ! 13: * The above copyright notice and this permission notice shall be included in ! 14: * all copies or substantial portions of the Software. ! 15: * ! 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ! 17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ! 19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ! 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ! 21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ! 22: * THE SOFTWARE. ! 23: */ ! 24: ! 25: #define TCG_TARGET_HPPA 1 ! 26: ! 27: #if defined(_PA_RISC1_1) ! 28: #define TCG_TARGET_REG_BITS 32 ! 29: #else ! 30: #error unsupported ! 31: #endif ! 32: ! 33: #define TCG_TARGET_WORDS_BIGENDIAN ! 34: ! 35: #define TCG_TARGET_NB_REGS 32 ! 36: ! 37: enum { ! 38: TCG_REG_R0 = 0, ! 39: TCG_REG_R1, ! 40: TCG_REG_RP, ! 41: TCG_REG_R3, ! 42: TCG_REG_R4, ! 43: TCG_REG_R5, ! 44: TCG_REG_R6, ! 45: TCG_REG_R7, ! 46: TCG_REG_R8, ! 47: TCG_REG_R9, ! 48: TCG_REG_R10, ! 49: TCG_REG_R11, ! 50: TCG_REG_R12, ! 51: TCG_REG_R13, ! 52: TCG_REG_R14, ! 53: TCG_REG_R15, ! 54: TCG_REG_R16, ! 55: TCG_REG_R17, ! 56: TCG_REG_R18, ! 57: TCG_REG_R19, ! 58: TCG_REG_R20, ! 59: TCG_REG_R21, ! 60: TCG_REG_R22, ! 61: TCG_REG_R23, ! 62: TCG_REG_R24, ! 63: TCG_REG_R25, ! 64: TCG_REG_R26, ! 65: TCG_REG_DP, ! 66: TCG_REG_RET0, ! 67: TCG_REG_RET1, ! 68: TCG_REG_SP, ! 69: TCG_REG_R31, ! 70: }; ! 71: ! 72: /* used for function call generation */ ! 73: #define TCG_REG_CALL_STACK TCG_REG_SP ! 74: #define TCG_TARGET_STACK_ALIGN 16 ! 75: #define TCG_TARGET_STACK_GROWSUP ! 76: ! 77: /* optional instructions */ ! 78: //#define TCG_TARGET_HAS_ext8s_i32 ! 79: //#define TCG_TARGET_HAS_ext16s_i32 ! 80: //#define TCG_TARGET_HAS_bswap16_i32 ! 81: //#define TCG_TARGET_HAS_bswap_i32 ! 82: ! 83: /* Note: must be synced with dyngen-exec.h */ ! 84: #define TCG_AREG0 TCG_REG_R17 ! 85: #define TCG_AREG1 TCG_REG_R14 ! 86: #define TCG_AREG2 TCG_REG_R15 ! 87: #define TCG_AREG3 TCG_REG_R16 ! 88: ! 89: static inline void flush_icache_range(unsigned long start, unsigned long stop) ! 90: { ! 91: start &= ~31; ! 92: while (start <= stop) ! 93: { ! 94: asm volatile ("fdc 0(%0)\n" ! 95: "sync\n" ! 96: "fic 0(%%sr4, %0)\n" ! 97: "sync\n" ! 98: : : "r"(start) : "memory"); ! 99: start += 32; ! 100: } ! 101: } ! 102: ! 103: /* supplied by libgcc */ ! 104: extern void *__canonicalize_funcptr_for_compare(void *); ! 105: ! 106: /* Field selection types defined by hppa */ ! 107: #define rnd(x) (((x)+0x1000)&~0x1fff) ! 108: /* lsel: select left 21 bits */ ! 109: #define lsel(v,a) (((v)+(a))>>11) ! 110: /* rsel: select right 11 bits */ ! 111: #define rsel(v,a) (((v)+(a))&0x7ff) ! 112: /* lrsel with rounding of addend to nearest 8k */ ! 113: #define lrsel(v,a) (((v)+rnd(a))>>11) ! 114: /* rrsel with rounding of addend to nearest 8k */ ! 115: #define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a))) ! 116: ! 117: #define mask(x,sz) ((x) & ~((1<<(sz))-1)) ! 118: ! 119: static inline int reassemble_12(int as12) ! 120: { ! 121: return (((as12 & 0x800) >> 11) | ! 122: ((as12 & 0x400) >> 8) | ! 123: ((as12 & 0x3ff) << 3)); ! 124: } ! 125: ! 126: static inline int reassemble_14(int as14) ! 127: { ! 128: return (((as14 & 0x1fff) << 1) | ! 129: ((as14 & 0x2000) >> 13)); ! 130: } ! 131: ! 132: static inline int reassemble_17(int as17) ! 133: { ! 134: return (((as17 & 0x10000) >> 16) | ! 135: ((as17 & 0x0f800) << 5) | ! 136: ((as17 & 0x00400) >> 8) | ! 137: ((as17 & 0x003ff) << 3)); ! 138: } ! 139: ! 140: static inline int reassemble_21(int as21) ! 141: { ! 142: return (((as21 & 0x100000) >> 20) | ! 143: ((as21 & 0x0ffe00) >> 8) | ! 144: ((as21 & 0x000180) << 7) | ! 145: ((as21 & 0x00007c) << 14) | ! 146: ((as21 & 0x000003) << 12)); ! 147: } ! 148: ! 149: static inline void hppa_patch21l(uint32_t *insn, int val, int addend) ! 150: { ! 151: val = lrsel(val, addend); ! 152: *insn = mask(*insn, 21) | reassemble_21(val); ! 153: } ! 154: ! 155: static inline void hppa_patch14r(uint32_t *insn, int val, int addend) ! 156: { ! 157: val = rrsel(val, addend); ! 158: *insn = mask(*insn, 14) | reassemble_14(val); ! 159: } ! 160: ! 161: static inline void hppa_patch17r(uint32_t *insn, int val, int addend) ! 162: { ! 163: val = rrsel(val, addend); ! 164: *insn = (*insn & ~0x1f1ffd) | reassemble_17(val); ! 165: } ! 166: ! 167: ! 168: static inline void hppa_patch21l_dprel(uint32_t *insn, int val, int addend) ! 169: { ! 170: register unsigned int dp asm("r27"); ! 171: hppa_patch21l(insn, val - dp, addend); ! 172: } ! 173: ! 174: static inline void hppa_patch14r_dprel(uint32_t *insn, int val, int addend) ! 175: { ! 176: register unsigned int dp asm("r27"); ! 177: hppa_patch14r(insn, val - dp, addend); ! 178: } ! 179: ! 180: static inline void hppa_patch17f(uint32_t *insn, int val, int addend) ! 181: { ! 182: int dot = (int)insn & ~0x3; ! 183: int v = ((val + addend) - dot - 8) / 4; ! 184: if (v > (1 << 16) || v < -(1 << 16)) { ! 185: printf("cannot fit branch to offset %d [%08x->%08x]\n", v, dot, val); ! 186: abort(); ! 187: } ! 188: *insn = (*insn & ~0x1f1ffd) | reassemble_17(v); ! 189: } ! 190: ! 191: static inline void hppa_load_imm21l(uint32_t *insn, int val, int addend) ! 192: { ! 193: /* Transform addil L'sym(%dp) to ldil L'val, %r1 */ ! 194: *insn = 0x20200000 | reassemble_21(lrsel(val, 0)); ! 195: } ! 196: ! 197: static inline void hppa_load_imm14r(uint32_t *insn, int val, int addend) ! 198: { ! 199: /* Transform ldw R'sym(%r1), %rN to ldo R'sym(%r1), %rN */ ! 200: hppa_patch14r(insn, val, addend); ! 201: /* HACK */ ! 202: if (addend == 0) ! 203: *insn = (*insn & ~0xfc000000) | (0x0d << 26); ! 204: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.