diff -aburN superopt-2.5-old/insn.def superopt-2.5/insn.def --- superopt-2.5-old/insn.def Tue May 16 17:13:22 1995 +++ superopt-2.5/insn.def Thu Jan 30 04:24:54 2003 @@ -359,6 +359,13 @@ DEF_INSN (CHKBIT, '<', "chkbit") DEF_INSN (NOTBIT, '2', "notbit") +/* Intel 386 specific instructions. */ +DEF_INSN (LEA_X2_386, '2', "lea_x2_386") +DEF_INSN (LEA_X4_386, '2', "lea_x4_386") +DEF_INSN (LEA_X8_386, '2', "lea_x8_386") +DEF_INSN (CHKBIT_386, '<', "chkbit_386") +DEF_INSN (CLTD_386, 'x', "cltd_386") + /* Local variables: mode:c diff -aburN superopt-2.5-old/run_program.def superopt-2.5/run_program.def --- superopt-2.5-old/run_program.def Thu May 18 17:03:01 1995 +++ superopt-2.5/run_program.def Thu Jan 30 06:36:45 2003 @@ -669,11 +669,17 @@ case SETBIT: PERFORM_SETBIT(v, co, r1, r2, ci); break; case CLRBIT: PERFORM_CLRBIT(v, co, r1, r2, ci); break; case CHKBIT: PERFORM_CHKBIT(v, co, r1, r2, ci); break; + case CHKBIT_386: PERFORM_CHKBIT_386(v, co, r1, r2, ci); break; case NOTBIT: PERFORM_NOTBIT(v, co, r1, r2, ci); break; #ifdef UDIV_WITH_SDIV case SDIV: PERFORM_SDIV(v, co, r1, r2, ci); break; #endif + + case LEA_X2_386: PERFORM_LEA_X2_386(v, co, r1, r2, ci); break; + case LEA_X4_386: PERFORM_LEA_X4_386(v, co, r1, r2, ci); break; + case LEA_X8_386: PERFORM_LEA_X8_386(v, co, r1, r2, ci); break; + case CLTD_386: PERFORM_CLTD_386(v, co, r1, ci); break; } #if HAS_NULLIFICATION diff -aburN superopt-2.5-old/superopt.c superopt-2.5/superopt.c --- superopt-2.5-old/superopt.c Fri Jun 2 20:29:35 1995 +++ superopt-2.5/superopt.c Thu Jan 30 05:42:08 2003 @@ -1046,7 +1046,26 @@ printf("decl %s",NAME(d)); else abort(); } - else abort(); + else + printf("leal (%s,%s),%s",NAME(s1),NAME(s2),NAME(d)); + break; + case LEA_X2_386: + if (IMMEDIATE_P(s1)) + printf("leal %d(,%s,2),%s",IMMEDIATE_VAL(s1),NAME(s2),NAME(d)); + else + printf("leal (%s,%s,2),%s",NAME(s1),NAME(s2),NAME(d)); + break; + case LEA_X4_386: + if (IMMEDIATE_P(s1)) + printf("leal %d(,%s,4),%s",IMMEDIATE_VAL(s1),NAME(s2),NAME(d)); + else + printf("leal (%s,%s,4),%s",NAME(s1),NAME(s2),NAME(d)); + break; + case LEA_X8_386: + if (IMMEDIATE_P(s1)) + printf("leal %d(,%s,8),%s",IMMEDIATE_VAL(s1),NAME(s2),NAME(d)); + else + printf("leal (%s,%s,8),%s",NAME(s1),NAME(s2),NAME(d)); break; case ADD_CO: printf("addl %s,%s",NAME(s2),NAME(d));break; @@ -1101,8 +1120,16 @@ printf("rrcl %s,%s",NAME(s2),NAME(d));break; case COMCY: printf("cmc");break; + case SETCY: + printf("stc");break; + case CLRCY: + printf("clc");break; + case CHKBIT_386: + printf("bt %s,%s",NAME(s2),NAME(s1));break; case MUL: printf("imull %s,%s",NAME(s2),NAME(d));break; + case CLTD_386: + printf("cltd");break; #elif PYR case COPY: printf("movw %s,%s",NAME(s1),NAME(d));break; diff -aburN superopt-2.5-old/superopt.h superopt-2.5/superopt.h --- superopt-2.5-old/superopt.h Wed May 17 18:58:31 1995 +++ superopt-2.5/superopt.h Thu Jan 30 06:29:34 2003 @@ -1436,6 +1436,17 @@ #define PERFORM_NOTBIT(d, co, r1, r2, ci) \ ((d) = (r1) ^ ((word) 1 << TRUNC_CNT(r2)), (co) = (ci)) +#define PERFORM_LEA_X2_386(d, co, r1, r2, ci) \ + ((d) = (r1) + 2*(r2), (co) = (ci)) +#define PERFORM_LEA_X4_386(d, co, r1, r2, ci) \ + ((d) = (r1) + 4*(r2), (co) = (ci)) +#define PERFORM_LEA_X8_386(d, co, r1, r2, ci) \ + ((d) = (r1) + 8*(r2), (co) = (ci)) +#define PERFORM_CHKBIT_386(d, co, r1, r2, ci) \ + ((co) = ((r1) >> TRUNC_CNT(r2)) & 1) +#define PERFORM_CLTD_386(d, co, r1, ci) \ + ((d) = (signed_word) (r1) < 0 ? -1 : 0, (co) = (ci)) + enum goal_func { #undef DEF_GOAL diff -aburN superopt-2.5-old/synth.def superopt-2.5/synth.def --- superopt-2.5-old/synth.def Wed May 24 09:14:55 1995 +++ superopt-2.5/synth.def Thu Jan 30 06:36:01 2003 @@ -2658,6 +2658,24 @@ PERFORM_ADD(v, co, r1, r2, ci); CRECURSE_2OP(ADD, s1, s1, s2, 1, prune_hint & ~CY_JUST_SET); #endif +#if I386 + /* i80386: lea (s1,s2),d */ + PERFORM_ADD(v, co, r1, r2, ci); + RECURSE(ADD, s1, s2, prune_hint & ~CY_JUST_SET); +#endif +#if I386 + /* i80386: lea (s1,s2,2),d */ + PERFORM_LEA_X2_386(v, co, r1, r2, ci); + RECURSE(LEA_X2_386, s1, s2, prune_hint & ~CY_JUST_SET); + + /* i80386: lea (s1,s2,4),d */ + PERFORM_LEA_X4_386(v, co, r1, r2, ci); + RECURSE(LEA_X4_386, s1, s2, prune_hint & ~CY_JUST_SET); + + /* i80386: lea (s1,s2,8),d */ + PERFORM_LEA_X8_386(v, co, r1, r2, ci); + RECURSE(LEA_X8_386, s1, s2, prune_hint & ~CY_JUST_SET); +#endif #if M68000 || I386 || PYR /* m68000: add i80386: add @@ -2760,6 +2778,7 @@ values[s2] = r2; } #endif + } } @@ -2945,6 +2964,13 @@ CRECURSE_2OP(ROTATEL_CO, s1, s1, CNST(cnt), SHIFT_COST(cnt), CY_JUST_SET); #endif } +#if I386 + for (cnt = 0; cnt < BITS_PER_WORD; cnt += (flag_shifts ? 1 : BITS_PER_WORD - 1)) + { + PERFORM_CHKBIT_386(v, co, r1, VALUE(cnt), ci); + CRECURSE_2OP(CHKBIT_386, n_values, s1, CNST(cnt), 1, CY_JUST_SET); + } +#endif } #endif #if MC68020 /* don't do this for plain 68000 */ @@ -3201,6 +3227,24 @@ CRECURSE_2OP(DECR_CYEQ, s1, s1, CNST(1), 1, CY_JUST_SET); } #endif +#if I386 + +#if 0 + /* redundant; same as lea (s1,s1),d */ + + /* i80386: lea 0(,s1,2),d */ + PERFORM_LEA_X2_386(v, co, VALUE(0), r1, ci); + RECURSE(LEA_X2_386, CNST(0), s1, prune_hint & ~CY_JUST_SET); +#endif + + /* i80386: lea 0(,s1,4),d */ + PERFORM_LEA_X4_386(v, co, VALUE(0), r1, ci); + RECURSE(LEA_X4_386, CNST(0), s1, prune_hint & ~CY_JUST_SET); + + /* i80386: lea 0(,s1,8),d */ + PERFORM_LEA_X8_386(v, co, VALUE(0), r1, ci); + RECURSE(LEA_X8_386, CNST(0), s1, prune_hint & ~CY_JUST_SET); +#endif } #if MC68020 /* don't do this for plain 68000 */ @@ -3336,15 +3380,27 @@ PERFORM_COPY(v, co, VALUE_MAX_SIGNED, ci); CRECURSE_NEW(COPY, n_values, CNST_0x7FFFFFFF, CNST(0), 2, prune_hint & ~CY_JUST_SET); #endif -#if SH - /* sh: sett */ +#if SH || I386 + /* sh: sett + i80386: stc */ co = 1; CRECURSE_2OP(SETCY, n_values, n_values, n_values, 1, CY_JUST_SET | CY_1); - /* sh: clrt */ + /* sh: clrt + i80386: clc */ co = 0; CRECURSE_2OP(CLRCY, n_values, n_values, n_values, 1, CY_JUST_SET | CY_0); #endif } + +#if I386 + PERFORM_CLTD_386(v, co, values[0], ci); + + if (n_values > 1) + CRECURSE_2OP(CLTD_386, 1, 0, 0, 1, prune_hint & ~CY_JUST_SET); + else + CRECURSE_NEW(CLTD_386, 1, 0, 0, 1, prune_hint & ~CY_JUST_SET); +#endif + #ifdef TIMING timings[allowed_cost] += cputime() - time_start; #endif