Fixup unaligned bwx instructions (ldwu, stw). This may fix some mysterious

natd sigbus errors being reported on the freebsd-alpha@ mailing list.

Obtained from: NetBSD
This commit is contained in:
Andrew Gallatin 2002-05-16 00:03:32 +00:00
parent fcbdc1f8a0
commit 16b9af9990
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96700

View File

@ -968,6 +968,11 @@ Gfloat_reg_cvt(input)
extern int alpha_unaligned_print, alpha_unaligned_fix;
extern int alpha_unaligned_sigbus;
struct unaligned_fixup_data {
const char *type; /* opcode name */
int size; /* size, 0 if fixup not supported */
};
int
unaligned_fixup(va, opcode, reg, td)
unsigned long va, opcode, reg;
@ -979,10 +984,11 @@ unaligned_fixup(va, opcode, reg, td)
struct proc *p;
unsigned long *regptr, longdata, uac;
int intdata; /* signed to get extension when storing */
struct {
const char *type; /* opcode name */
int size; /* size, 0 if fixup not supported */
} tab[0x10] = {
u_int16_t worddata; /* unsigned to _avoid_ extension */
const struct unaligned_fixup_data tab_0c[0x2] = {
{ "ldwu", 2 }, { "stw", 2 },
};
const struct unaligned_fixup_data tab_20[0x10] = {
#ifdef FIX_UNALIGNED_VAX_FP
{ "ldf", 4 }, { "ldg", 8 },
#else
@ -1022,9 +1028,12 @@ unaligned_fixup(va, opcode, reg, td)
* Find out which opcode it is. Arrange to have the opcode
* printed if it's an unknown opcode.
*/
if (opcode >= 0x20 && opcode <= 0x2f) {
type = tab[opcode - 0x20].type;
size = tab[opcode - 0x20].size;
if (opcode >= 0x0c && opcode <= 0x0d) {
type = tab_0c[opcode - 0x0c].type;
size = tab_0c[opcode - 0x0c].size;
} else if (opcode >= 0x20 && opcode <= 0x2f) {
type = tab_20[opcode - 0x20].type;
size = tab_20[opcode - 0x20].size;
} else {
type = "0x%lx";
size = 0;
@ -1067,6 +1076,15 @@ unaligned_fixup(va, opcode, reg, td)
signal = SIGBUS;
if (dofix && size != 0) {
switch (opcode) {
case 0x0c: /* ldwu */
/* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
unaligned_load_integer(worddata);
break;
case 0x0d: /* stw */
/* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
unaligned_store_integer(worddata);
break;
#ifdef FIX_UNALIGNED_VAX_FP
case 0x20: /* ldf */
unaligned_load_floating(intdata, Ffloat_to_reg);