summaryrefslogtreecommitdiff
path: root/dyngen.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-06-14 17:32:25 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-06-14 17:32:25 +0000
commitfdbb46910a2033bd748681346d4261725f5e184b (patch)
tree366d6f921fbca0bbfd6afa63078bd91716d1aff3 /dyngen.c
parent43057ab1272ba2b9b052b19a3453fb0f3b510149 (diff)
downloadqemu-fdbb46910a2033bd748681346d4261725f5e184b.tar.gz
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.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/dyngen.c b/dyngen.c
index ed580ff5c2..a8e2958e87 100644
--- a/dyngen.c
+++ b/dyngen.c
@@ -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);
}