diff --git a/mach/mips/mcg/table b/mach/mips/mcg/table index f1701813e..ff4d77e28 100644 --- a/mach/mips/mcg/table +++ b/mach/mips/mcg/table @@ -306,20 +306,38 @@ PATTERNS emit "lhu %out, %addr" cost 4; + out:(int)reg = EXTENDH.I(LOADH.I(addr:address)) + emit "lh %out, %addr" + cost 4; + out:(int)ushort0 = LOADH.I(label:LABEL.I) emit "lui at, ha16[$label]" emit "lhu %out, lo16[$label] (at)" cost 8; + out:(int)reg = EXTENDH.I(LOADH.I(label:LABEL.I)) + emit "lui at, ha16[$label]" + emit "lh %out, lo16[$label] (at)" + cost 8; + out:(int)ubyte0 = LOADB.I(addr:address) emit "lbu %out, %addr" cost 4; + out:(int)reg = EXTENDB.I(LOADB.I(addr:address)) + emit "lb %out, %addr" + cost 4; + out:(int)ubyte0 = LOADB.I(label:LABEL.I) emit "lui at, ha16[$label]" emit "lbu %out, lo16[$label] (at)" cost 8; + out:(int)reg = EXTENDB.I(LOADB.I(label:LABEL.I)) + emit "lui at, ha16[$label]" + emit "lb %out, lo16[$label] (at)" + cost 8; + out:(float)reg = LOAD.F(addr:address) emit "lwc1 %out, %addr" cost 4; diff --git a/mach/mips/top/table b/mach/mips/top/table index 8f6a5d6d7..c0037f54d 100644 --- a/mach/mips/top/table +++ b/mach/mips/top/table @@ -7,14 +7,41 @@ LABEL_STARTER '.'; %%; X, Y, Z { TRUE }; +R { TRUE }; %%; /* Whitespace is significant here! */ -addiu RNZ, RNZ, 0 -> ; +addiu R, R, X : addiu R, R, Y { plus(X, Y, Z) } -> addiu R, R, Z ; + +addiu X, X, 0 -> ; b X : nop : labdef X -> labdef X ; %%; +/* Does it fit a signed 16-bit integer? */ +static int fits16(long l) { + return l >= -32768 && l <= 32767; +} + +/* Tries sum = a + b with signed 16-bit integers. */ +int plus(const char *a, const char *b, const char *sum) +{ + long la, lb, lsum; + char *end; + + la = strtol(a, &end, 10); + if (*a == '\0' || *end != '\0' || !fits16(la)) + return 0; + lb = strtol(b, &end, 10); + if (*b == '\0' || *end != '\0' || !fits16(lb)) + return 0; + + lsum = la + lb; + if (!fits16(lsum)) + return 0; + snprintf(sum, 7, "%ld", lsum); + return 1; +}