Annotation of hatari/src/cpu/jit/compemu_optimizer_x86.c, revision 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.