diff options
| author | David Boddie <david@boddie.org.uk> | 2022-01-18 23:17:22 +0100 |
|---|---|---|
| committer | David Boddie <david@boddie.org.uk> | 2023-11-16 16:44:27 +0100 |
| commit | db3257ec1eca2eb282aa53e1822fd5fd92768b1a (patch) | |
| tree | 404ab2ff854b54a60fc0f982a90186012f3c4bdf /utils/tl/thumb.c | |
| parent | 01ae1f3b4a7aa5bf32e3ad3c2911e6f6ba723e71 (diff) | |
Handled loads and stores using different base registers with slightly different instructions.
Diffstat (limited to 'utils/tl/thumb.c')
| -rw-r--r-- | utils/tl/thumb.c | 38 |
1 files changed, 28 insertions, 10 deletions
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 */ |
