Annotation of hatari/src/cpu/jit/compemu_optimizer_x86.c, revision 1.1.1.1

1.1       root        1: #if USE_LOW_OPTIMIZER
                      2: /* Welcome to the magical world of cpp ;-) */
                      3: 
                      4: /* This was broken by the advent of FPU emulation. It also didn't
                      5:    provide any useful speedup while it worked. *Sigh* Someone fix my
                      6:    software, please ;-) */
                      7: 
                      8: #define MAXLOPTINST 100
                      9: 
                     10: #define LDECISION currprefs.comp_lowopt
                     11: 
                     12: #define lopt_op0(dummy) lopt_store_op0(
                     13: #define lopt_op1(a1) lopt_store_op1(LOPT_##a1,
                     14: #define lopt_op2(a1,a2) lopt_store_op2(LOPT_##a1,LOPT_##a2,
                     15: #define lopt_op3(a1,a2,a3) lopt_store_op3(LOPT_##a1,LOPT_##a2,LOPT_##a3,
                     16: #define lopt_op4(a1,a2,a3,a4) lopt_store_op4(LOPT_##a1,LOPT_##a2,LOPT_##a3,LOPT_##a4,
                     17: #define lopt_op5(a1,a2,a3,a4,a5) lopt_store_op5(LOPT_##a1,LOPT_##a2,LOPT_##a3,LOPT_##a4,LOPT_##a5,
                     18: 
                     19: #define ldirect0(dummy) ()
                     20: #define ldirect1(a1) (LDIR_##a1)
                     21: #define ldirect2(a1,a2) (LDIR_##a1,LDIR_##a2)
                     22: #define ldirect3(a1,a2,a3) (LDIR_##a1,LDIR_##a2,LDIR_##a3)
                     23: #define ldirect4(a1,a2,a3,a4) (LDIR_##a1,LDIR_##a2,LDIR_##a3,LDIR_##a4)
                     24: #define ldirect5(a1,a2,a3,a4,a5) (LDIR_##a1,LDIR_##a2,LDIR_##a3,LDIR_##a4,LDIR_##a5)
                     25: 
                     26: #define NONE 0
                     27: #define READ 1
                     28: #define WRITE 2
                     29: #define RMW (READ|WRITE)
                     30: 
                     31: #define SIZE1 4
                     32: #define SIZE2 8
                     33: #define SIZE4 12
                     34: #define FLOAT 16
                     35: #define SIZEMASK 12
                     36: 
                     37: #define LIMM NONE
                     38: #define LR1  (READ | SIZE1)
                     39: #define LR2  (READ | SIZE2)
                     40: #define LR4  (READ | SIZE4)
                     41: #define LW1  (WRITE | SIZE1)
                     42: #define LW2  (WRITE | SIZE2)
                     43: #define LW4  (WRITE | SIZE4)
                     44: #define LRW1 (RMW | SIZE1)
                     45: #define LRW2 (RMW | SIZE2)
                     46: #define LRW4 (RMW | SIZE4)
                     47: #define LFW  (READ | FLOAT)
                     48: #define LFR  (WRITE | FLOAT)
                     49: #define LFRW (RMW | FLOAT)
                     50: #define LMEMR NONE
                     51: #define LMEMW NONE
                     52: #define LMEMRW NONE
                     53: 
                     54: #define LOPT_IMM LIMM,
                     55: #define LOPT_R1  LR1 ,
                     56: #define LOPT_R2  LR2 ,
                     57: #define LOPT_R4  LR4 ,
                     58: #define LOPT_W1  LW1 ,
                     59: #define LOPT_W2  LW2 ,
                     60: #define LOPT_W4  LW4 ,
                     61: #define LOPT_RW1 LRW1,
                     62: #define LOPT_RW2 LRW2,
                     63: #define LOPT_RW4 LRW4,
                     64: #define LOPT_FR  LFR,
                     65: #define LOPT_FW  LFW,
                     66: #define LOPT_FRW LFRW,
                     67: #define LOPT_MEMR LMEMR,
                     68: #define LOPT_MEMW LMEMW,
                     69: #define LOPT_MEMRW LMEMRW,
                     70: 
                     71: #define LDIR_IMM
                     72: #define LDIR_R1
                     73: #define LDIR_R2
                     74: #define LDIR_R4
                     75: #define LDIR_W1
                     76: #define LDIR_W2
                     77: #define LDIR_W4
                     78: #define LDIR_RW1
                     79: #define LDIR_RW2
                     80: #define LDIR_RW4
                     81: #define LDIR_FW
                     82: #define LDIR_FR
                     83: #define LDIR_FRW
                     84: #define LDIR_MEMR
                     85: #define LDIR_MEMW
                     86: #define LDIR_MEMRW
                     87: 
                     88: 
                     89: #undef LOWFUNC
                     90: #undef LENDFUNC
                     91: 
                     92: #define LOWFUNC(flags,mem,nargs,func,args) \
                     93:   STATIC_INLINE void do_##func args
                     94: 
                     95: #define LENDFUNC(flags,mem,nargs,func,args) \
                     96:   STATIC_INLINE void func args \
                     97:   { \
                     98:   if (LDECISION) { \
                     99:     lopt_op##nargs##args do_##func, mem, flags); \
                    100:   } else { \
                    101:     do_##func ldirect##nargs##args; \
                    102:   } \
                    103:   }
                    104: 
                    105: typedef struct lopt_inst_rec {
                    106:     void* func;
                    107:     uae_u32 args[5];
                    108:     uae_u8 argtype[5];
                    109:     uae_s8 nargs;
                    110:     uae_u8 mem;
                    111:     uae_u8 flags;
                    112: } lopt_inst;
                    113: 
                    114: 
                    115: 
                    116: static lopt_inst linst[MAXLOPTINST];
                    117: static int lopt_index=0;
                    118: 
                    119: STATIC_INLINE int argsize(int type)
                    120: {
                    121:     return type&SIZEMASK;
                    122: }
                    123: 
                    124: STATIC_INLINE int reads_mem(int i) {
                    125:     return linst[i].mem & READ;
                    126: }
                    127: 
                    128: 
                    129: STATIC_INLINE int access_reg(int i, int r, int mode)
                    130: {
                    131:     int k;
                    132:     for (k=0;k<linst[i].nargs;k++)
                    133:        if (linst[i].args[k]==r &&
                    134:            (linst[i].argtype[k]&mode) &&
                    135:            !(linst[i].argtype[k]&FLOAT))
                    136:            return 1;
                    137:     return 0;
                    138: }
                    139: 
                    140: STATIC_INLINE_ int writes_reg(int i, int r)
                    141: {
                    142:     return access_reg(i,r,WRITE);
                    143: }
                    144: 
                    145: STATIC_INLINE int reads_reg(int i, int r)
                    146: {
                    147:     return access_reg(i,r,READ);
                    148: }
                    149: 
                    150: STATIC_INLINE int uses_reg(int i, int r)
                    151: {
                    152:     return access_reg(i,r,RMW);
                    153: }
                    154: 
                    155: 
                    156: STATIC_INLINE int writes_mem(int i) {
                    157:     return linst[i].mem & WRITE;
                    158: }
                    159: 
                    160: STATIC_INLINE int uses_mem(int i)
                    161: {
                    162:     return linst[i].mem & RMW;
                    163: }
                    164: 
                    165: STATIC_INLINE int reads_flags(int i) {
                    166:     return linst[i].flags & READ;
                    167: }
                    168: 
                    169: STATIC_INLINE int writes_flags(int i) {
                    170:     return linst[i].flags & WRITE;
                    171: }
                    172: 
                    173: STATIC_INLINE int uses_flags(int i)
                    174: {
                    175:     return linst[i].flags & RMW;
                    176: }
                    177: 
                    178: static void do_raw_mov_l_rm(W4,MEMR);
                    179: static void do_raw_fflags_save(void);
                    180: 
                    181: 
                    182: /* Whether i depends on j */
                    183: STATIC_INLINE int depends_on(int i, int j)
                    184: {
                    185:     int n;
                    186: 
                    187:     /* First, check memory */
                    188:     if (writes_mem(i) && uses_mem(j))
                    189:        return 1;
                    190:     if (reads_mem(i) && writes_mem(j))
                    191:        return 1;
                    192: 
                    193:     /* Next, check flags */
                    194:     if (writes_flags(i) && uses_flags(j))
                    195:        return 1;
                    196:     if (reads_flags(i) && writes_flags(j))
                    197:        return 1;
                    198: 
                    199:     for (n=0;n<linst[i].nargs;n++) {
                    200:        if (linst[i].argtype[n] & FLOAT)
                    201:            return 1;
                    202:     }
                    203:     for (n=0;n<linst[j].nargs;n++) {
                    204:        if (linst[j].argtype[n] & FLOAT)
                    205:            return 1;
                    206:     }
                    207: 
                    208:     for (n=0;n<linst[i].nargs;n++) {
                    209:        if ((linst[i].argtype[n] & WRITE) &&
                    210:            !(linst[i].argtype[n] & FLOAT)) {
                    211:            if (uses_reg(j,linst[i].args[n]))
                    212:                return 1;
                    213:        }
                    214:        else if ((linst[i].argtype[n] & READ) &&
                    215:                 !(linst[i].argtype[n] & FLOAT))  {
                    216:            if (writes_reg(j,linst[i].args[n]))
                    217:                return 1;
                    218:        }
                    219:     }
                    220: 
                    221:     /* The need for this indicates a problem somewhere in the
                    222:        LOWFUNC definitions --- I think. FIXME! */
                    223: 
                    224:     if (uses_flags(j) && uses_flags(i))
                    225:        return 1;
                    226:     if (linst[i].func==do_raw_fflags_save)
                    227:        return 1;
                    228:     if (linst[j].func==do_raw_fflags_save)
                    229:        return 1;
                    230: 
                    231:     return 0;
                    232: }
                    233: 
                    234: static void do_raw_mov_l_rm(W4 d, MEMR s);
                    235: 
                    236: STATIC_INLINE void low_peephole(void)
                    237: {
                    238:     int i;
                    239: 
                    240:     for (i=0;i<lopt_index;i++) {
                    241:        if (uses_mem(i)) {
                    242:            int j=i-1;
                    243: 
                    244:            while (j>=i-4 && j>=0 && !depends_on(i,j)) {
                    245:                j--;
                    246:            }
                    247:            if (j!=i-1) {
                    248:                lopt_inst x=linst[i];
                    249:                int k=i;
                    250: 
                    251:                j++;
                    252:                while (k>j) {
                    253:                    linst[k]=linst[k-1];
                    254:                    k--;
                    255:                }
                    256:                linst[j]=x;
                    257:            }
                    258:        }
                    259:     }
                    260: }
                    261: 
                    262: 
                    263: typedef void lopt_handler0(void);
                    264: typedef void lopt_handler1(uae_u32);
                    265: typedef void lopt_handler2(uae_u32,uae_u32);
                    266: typedef void lopt_handler3(uae_u32,uae_u32,uae_u32);
                    267: typedef void lopt_handler4(uae_u32,uae_u32,uae_u32,uae_u32);
                    268: typedef void lopt_handler5(uae_u32,uae_u32,uae_u32,uae_u32,uae_u32);
                    269: 
                    270: static void lopt_emit_all(void)
                    271: {
                    272:     int i;
                    273:     lopt_inst* x;
                    274:     static int inemit=0;
                    275: 
                    276:     if (inemit) {
                    277:        printf("WARNING: lopt_emit is not reentrant!\n");
                    278:     }
                    279:     inemit=1;
                    280: 
                    281:     low_peephole();
                    282: 
                    283:     for (i=0;i<lopt_index;i++) {
                    284:        x=linst+i;
                    285:        switch(x->nargs) {
                    286:         case 0: ((lopt_handler0*)x->func)(); break;
                    287:         case 1: ((lopt_handler1*)x->func)(x->args[0]); break;
                    288:         case 2: ((lopt_handler2*)x->func)(x->args[0],x->args[1]); break;
                    289:         case 3: ((lopt_handler3*)x->func)(x->args[0],x->args[1],x->args[2]); break;
                    290:         case 4: ((lopt_handler4*)x->func)(x->args[0],x->args[1],x->args[2],
                    291:                                           x->args[3]); break;
                    292:         case 5: ((lopt_handler5*)x->func)(x->args[0],x->args[1],x->args[2],
                    293:                                           x->args[3],x->args[4]); break;
                    294:         default: abort();
                    295:        }
                    296:     }
                    297:     lopt_index=0;
                    298:     inemit=0;
                    299: }
                    300: 
                    301: STATIC_INLINE void low_advance(void)
                    302: {
                    303:   lopt_index++;
                    304:   if (lopt_index==MAXLOPTINST)
                    305:     lopt_emit_all();
                    306: }
                    307: 
                    308: STATIC_INLINE void lopt_store_op0(void* lfuncptr, uae_u32 lmem,
                    309:                                      uae_u32 lflags)
                    310: {
                    311:   linst[lopt_index].func=lfuncptr;
                    312:   linst[lopt_index].mem=lmem;
                    313:   linst[lopt_index].flags=lflags;
                    314:   linst[lopt_index].nargs=0;
                    315:   low_advance();
                    316: }
                    317: 
                    318: STATIC_INLINE void lopt_store_op1(uae_u8 t1, uae_u32 a1,
                    319:                                      void* lfuncptr, uae_u32 lmem,
                    320:                                      uae_u32 lflags)
                    321: {
                    322:   linst[lopt_index].func=lfuncptr;
                    323:   linst[lopt_index].mem=lmem;
                    324:   linst[lopt_index].flags=lflags;
                    325:   linst[lopt_index].nargs=1;
                    326:   linst[lopt_index].argtype[0]=t1;
                    327:   linst[lopt_index].args[0]=a1;
                    328:   low_advance();
                    329: }
                    330: 
                    331: STATIC_INLINE void lopt_store_op2(uae_u8 t1, uae_u32 a1,
                    332:                                      uae_u8 t2, uae_u32 a2,
                    333:                                      void* lfuncptr, uae_u32 lmem,
                    334:                                      uae_u32 lflags)
                    335: {
                    336:   linst[lopt_index].func=lfuncptr;
                    337:   linst[lopt_index].mem=lmem;
                    338:   linst[lopt_index].flags=lflags;
                    339:   linst[lopt_index].nargs=2;
                    340:   linst[lopt_index].argtype[0]=t1;
                    341:   linst[lopt_index].args[0]=a1;
                    342:   linst[lopt_index].argtype[1]=t2;
                    343:   linst[lopt_index].args[1]=a2;
                    344:   low_advance();
                    345: }
                    346: 
                    347: STATIC_INLINE void lopt_store_op3(uae_u8 t1, uae_u32 a1,
                    348:                                      uae_u8 t2, uae_u32 a2,
                    349:                                      uae_u8 t3, uae_u32 a3,
                    350:                                      void* lfuncptr, uae_u32 lmem,
                    351:                                      uae_u32 lflags)
                    352: {
                    353:   linst[lopt_index].func=lfuncptr;
                    354:   linst[lopt_index].mem=lmem;
                    355:   linst[lopt_index].flags=lflags;
                    356:   linst[lopt_index].nargs=3;
                    357:   linst[lopt_index].argtype[0]=t1;
                    358:   linst[lopt_index].args[0]=a1;
                    359:   linst[lopt_index].argtype[1]=t2;
                    360:   linst[lopt_index].args[1]=a2;
                    361:   linst[lopt_index].argtype[2]=t3;
                    362:   linst[lopt_index].args[2]=a3;
                    363:   low_advance();
                    364: }
                    365: 
                    366: STATIC_INLINE void lopt_store_op4(uae_u8 t1, uae_u32 a1,
                    367:                                      uae_u8 t2, uae_u32 a2,
                    368:                                      uae_u8 t3, uae_u32 a3,
                    369:                                      uae_u8 t4, uae_u32 a4,
                    370:                                      void* lfuncptr, uae_u32 lmem,
                    371:                                      uae_u32 lflags)
                    372: {
                    373:   linst[lopt_index].func=lfuncptr;
                    374:   linst[lopt_index].mem=lmem;
                    375:   linst[lopt_index].flags=lflags;
                    376:   linst[lopt_index].nargs=4;
                    377:   linst[lopt_index].argtype[0]=t1;
                    378:   linst[lopt_index].args[0]=a1;
                    379:   linst[lopt_index].argtype[1]=t2;
                    380:   linst[lopt_index].args[1]=a2;
                    381:   linst[lopt_index].argtype[2]=t3;
                    382:   linst[lopt_index].args[2]=a3;
                    383:   linst[lopt_index].argtype[3]=t4;
                    384:   linst[lopt_index].args[3]=a4;
                    385:   low_advance();
                    386: }
                    387: 
                    388: STATIC_INLINE void lopt_store_op5(uae_u8 t1, uae_u32 a1,
                    389:                                      uae_u8 t2, uae_u32 a2,
                    390:                                      uae_u8 t3, uae_u32 a3,
                    391:                                      uae_u8 t4, uae_u32 a4,
                    392:                                      uae_u8 t5, uae_u32 a5,
                    393:                                      void* lfuncptr, uae_u32 lmem,
                    394:                                      uae_u32 lflags)
                    395: {
                    396:   linst[lopt_index].func=lfuncptr;
                    397:   linst[lopt_index].mem=lmem;
                    398:   linst[lopt_index].flags=lflags;
                    399:   linst[lopt_index].nargs=5;
                    400:   linst[lopt_index].argtype[0]=t1;
                    401:   linst[lopt_index].args[0]=a1;
                    402:   linst[lopt_index].argtype[1]=t2;
                    403:   linst[lopt_index].args[1]=a2;
                    404:   linst[lopt_index].argtype[2]=t3;
                    405:   linst[lopt_index].args[2]=a3;
                    406:   linst[lopt_index].argtype[3]=t4;
                    407:   linst[lopt_index].args[3]=a4;
                    408:   linst[lopt_index].argtype[4]=t5;
                    409:   linst[lopt_index].args[4]=a5;
                    410:   low_advance();
                    411: }
                    412: 
                    413: STATIC_INLINE void empty_low_optimizer(void)
                    414: {
                    415:   lopt_emit_all();
                    416: }
                    417: 
                    418: #else
                    419: #define lopt_emit_all()
                    420: #define empty_low_optimizer()
                    421: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.