sim/h8300/compile.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/sim/h8300/compile.c b/sim/h8300/compile.c index 06988095228..3cca69730b0 100644 --- a/sim/h8300/compile.c +++ b/sim/h8300/compile.c @@ -1586,6 +1586,7 @@ instruction_comparator (const void *p1_, const void *p2_) { struct h8_opcode *p1 = (struct h8_opcode *)p1_; struct h8_opcode *p2 = (struct h8_opcode *)p2_; + int cmp; /* The 1st sort key is based on whether or not the instruction is even available. This reduces the @@ -1605,7 +1606,43 @@ instruction_comparator (const void *p1_, const void *p2_) return p2_available - p1_available; /* Secondarily sort based on the first opcode nibble. */ - return p1->data.nib[0] - p2->data.nib[0]; + if (p1->data.nib[0] != p2->data.nib[0]) + return p1->data.nib[0] - p2->data.nib[0]; + + /* The 3rd sort key */ + cmp = strcmp(p1->name, p2->name); + if (cmp) + { + /* Two different opcodes */ + size_t l1 = strlen(p1->name); + size_t l2 = strlen(p2->name); + ptrdiff_t i1 = strchr(p1->name, '.') - p1->name; + ptrdiff_t i2 = strchr(p2->name, '.') - p2->name; + char c1, c2; + + if ((l1 == l2) && (i1 == i2) && (i1 > 0)) + { + /* Check for different mnemonics, e.g. add.w vs. and.b */ + cmp = strncmp(p1->name, p2->name, i1); + if (cmp) + return cmp; + + /* At this point we expect only b, w or l suffix, + where b < w < l */ + c1 = p1->name[i1+1]; + c2 = p2->name[i2+1]; + if (c1 == 'b') + return -1; + else if (c1 == 'w') + return (c2 == 'b') ? 1 : -1; + else + return 1; + } + return cmp; + } + + /* The 4th sort key */ + return p1->how - p2->how; }