diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-06-14 17:32:25 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-06-14 17:32:25 +0000 |
commit | fdbb46910a2033bd748681346d4261725f5e184b (patch) | |
tree | 366d6f921fbca0bbfd6afa63078bd91716d1aff3 /dyngen.c | |
parent | 43057ab1272ba2b9b052b19a3453fb0f3b510149 (diff) |
Solaris/SPARC host port (Ben Taylor)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1979 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'dyngen.c')
-rw-r--r-- | dyngen.c | 29 |
1 files changed, 26 insertions, 3 deletions
@@ -1440,6 +1440,12 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, } #elif defined(HOST_SPARC) { +#define INSN_SAVE 0x9de3a000 +#define INSN_RET 0x81c7e008 +#define INSN_RESTORE 0x81e80000 +#define INSN_RETURN 0x81cfe008 +#define INSN_NOP 0x01000000 + uint32_t start_insn, end_insn1, end_insn2; uint8_t *p; p = (void *)(p_end - 8); @@ -1448,12 +1454,17 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, start_insn = get32((uint32_t *)(p_start + 0x0)); end_insn1 = get32((uint32_t *)(p + 0x0)); end_insn2 = get32((uint32_t *)(p + 0x4)); - if ((start_insn & ~0x1fff) == 0x9de3a000) { + if ((start_insn & ~0x1fff) == INSN_SAVE) { p_start += 0x4; start_offset += 0x4; if ((int)(start_insn | ~0x1fff) < -128) error("Found bogus save at the start of %s", name); - if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000) + if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE) + /* SPARC v7: ret; restore; */ ; + else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP) + /* SPARC v9: return; nop; */ ; + else + error("ret; restore; not found at end of %s", name); } else { error("No save at the beginning of %s", name); @@ -1462,7 +1473,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, /* Skip a preceeding nop, if present. */ if (p > p_start) { skip_insn = get32((uint32_t *)(p - 0x4)); - if (skip_insn == 0x01000000) + if (skip_insn == INSN_NOP) p -= 4; } #endif @@ -2151,6 +2162,18 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, reloc_offset, reloc_offset, name, addend, reloc_offset); break; + case R_SPARC_WDISP22: + fprintf(outfile, + " *(uint32_t *)(gen_code_ptr + %d) = " + "((*(uint32_t *)(gen_code_ptr + %d)) " + " & ~0x3fffff) " + " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) " + " & 0x3fffff);\n", + rel->r_offset - start_offset, + rel->r_offset - start_offset, + name, addend, + rel->r_offset - start_offset); + break; default: error("unsupported sparc relocation (%d)", type); } |