From db3257ec1eca2eb282aa53e1822fd5fd92768b1a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 18 Jan 2022 23:17:22 +0100 Subject: Handled loads and stores using different base registers with slightly different instructions. --- utils/tl/thumb.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'utils') diff --git a/utils/tl/thumb.c b/utils/tl/thumb.c index ab878836..c150c808 100644 --- a/utils/tl/thumb.c +++ b/utils/tl/thumb.c @@ -464,11 +464,11 @@ Optab thumboptab[] = { AMOVF, C_FAUTO,C_NONE, C_FREG, 53, 4, REGSP }, { AMOVF, C_FOREG,C_NONE, C_FREG, 53, 4, 0 }, - { AMOVF, C_FREG, C_NONE, C_LEXT, 54, 8, REGSB, LTO }, + { AMOVF, C_FREG, C_NONE, C_LEXT, 54, 6, REGSB, LTO }, { AMOVF, C_FREG, C_NONE, C_LAUTO, 54, 8, REGSP, LTO }, { AMOVF, C_FREG, C_NONE, C_LOREG, 54, 8, 0, LTO }, - { AMOVF, C_LEXT, C_NONE, C_FREG, 55, 8, REGSB, LFROM }, + { AMOVF, C_LEXT, C_NONE, C_FREG, 55, 6, REGSB, LFROM }, { AMOVF, C_LAUTO,C_NONE, C_FREG, 55, 8, REGSP, LFROM }, { AMOVF, C_LOREG,C_NONE, C_FREG, 55, 8, 0, LFROM }, @@ -1202,29 +1202,47 @@ if(debug['G']) print("%ulx: %s: thumb\n", (ulong)(p->pc), p->from.sym->name); break; case 54: /* floating point store, long offset UGLY */ + /* Load an address or offset from a PC-relative address */ o1 = thumbomvl(p, &p->to, REGTMPT); if(!o1) break; r = p->to.reg; if(r == NREG) r = o->param; - /* ADD (ARM ARM Thumb-2 Supplement, 4.6.4), T2 */ - o2 = 0x4400 | ((REGTMPT & 0x8) << 4) | (r << 3) | (REGTMPT & 0x7); - o3 = thumbofsr(p->as, p->from.reg, 0, REGTMPT, p); - SPLIT_INS(o3, o4) + if (o->param == REGSB) { + /* Store directly to the address */ + o2 = thumbofsr(p->as, p->from.reg, 0, REGTMPT, p); + SPLIT_INS(o2, o3) + } else { + /* Add the offset to the stack pointer */ + /* ADD (ARM ARM Thumb-2 Supplement, 4.6.4), T2 */ + o2 = 0x4400 | ((REGTMPT & 0x8) << 4) | (r << 3) | (REGTMPT & 0x7); + /* Store to the calculated address */ + o3 = thumbofsr(p->as, p->from.reg, 0, REGTMPT, p); + SPLIT_INS(o3, o4) + } break; case 55: /* floating point load, long offset UGLY */ + /* Load an address or offset from a PC-relative address */ o1 = thumbomvl(p, &p->from, REGTMPT); if(!o1) break; r = p->from.reg; if(r == NREG) r = o->param; - /* ADD (ARM ARM Thumb-2 Supplement, 4.6.4), T2 */ - o2 = 0x4400 | ((REGTMPT & 0x8) << 4) | (r << 3) | (REGTMPT & 0x7); - o3 = thumbofsr(p->as, p->to.reg, 0, REGTMPT, p) | (1<<4); - SPLIT_INS(o3, o4) + if (o->param == REGSB) { + /* Load directly from the address */ + o2 = thumbofsr(p->as, p->to.reg, 0, REGTMPT, p) | (1<<4); + SPLIT_INS(o2, o3) + } else { + /* Add the offset to the stack pointer */ + /* ADD (ARM ARM Thumb-2 Supplement, 4.6.4), T2 */ + o2 = 0x4400 | ((REGTMPT & 0x8) << 4) | (r << 3) | (REGTMPT & 0x7); + /* Load from the calculated address */ + o3 = thumbofsr(p->as, p->to.reg, 0, REGTMPT, p) | (1<<4); + SPLIT_INS(o3, o4) + } break; case 56: /* floating point arith */ -- cgit v1.2.3