emit_mips.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465
  1. /*
  2. * Basic macros to emit MIPS II/MIPS32 Release 1 instructions and some utils
  3. * Copyright (C) 2019 kub
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. */
  8. #define HOST_REGS 32
  9. #define CONTEXT_REG 23 // s7
  10. #define RET_REG 2 // v0
  11. // NB: the ubiquitous JZ74[46]0 uses MIPS32 Release 1, a slight MIPS II superset
  12. // registers usable for user code: r1-r25, others reserved or special
  13. #define Z0 0 // zero register
  14. #define GP 28 // global pointer
  15. #define SP 29 // stack pointer
  16. #define FP 30 // frame pointer
  17. #define LR 31 // link register
  18. // internally used by code emitter:
  19. #define AT 1 // used to hold intermediate results
  20. #define FNZ 15 // emulated processor flags: N (bit 31) ,Z (all bits)
  21. #define FC 24 // emulated processor flags: C (bit 0), others 0
  22. #define FV 25 // emulated processor flags: Nt^Ns (bit 31). others ?
  23. // unified conditions; virtual, not corresponding to anything real on MIPS
  24. #define DCOND_EQ 0x0
  25. #define DCOND_NE 0x1
  26. #define DCOND_HS 0x2
  27. #define DCOND_LO 0x3
  28. #define DCOND_MI 0x4
  29. #define DCOND_PL 0x5
  30. #define DCOND_VS 0x6
  31. #define DCOND_VC 0x7
  32. #define DCOND_HI 0x8
  33. #define DCOND_LS 0x9
  34. #define DCOND_GE 0xa
  35. #define DCOND_LT 0xb
  36. #define DCOND_GT 0xc
  37. #define DCOND_LE 0xd
  38. #define DCOND_CS DCOND_LO
  39. #define DCOND_CC DCOND_HS
  40. // unified insn
  41. #define MIPS_INSN(op, rs, rt, rd, sa, fn) \
  42. (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|((fn)<<0))
  43. #define _ 0 // marker for "field unused"
  44. #define __(n) o##n // enum marker for "undefined"
  45. // opcode field (encoded in op)
  46. enum { OP__FN=000, OP__RT, OP_J, OP_JAL, OP_BEQ, OP_BNE, OP_BLEZ, OP_BGTZ };
  47. enum { OP_ADDI=010, OP_ADDIU, OP_SLTI, OP_SLTIU, OP_ANDI, OP_ORI, OP_XORI, OP_LUI };
  48. enum { OP_LB=040, OP_LH, OP_LWL, OP_LW, OP_LBU, OP_LHU, OP_LWR };
  49. enum { OP_SB=050, OP_SH, OP_SWL, OP_SW, __(54), __(55), OP_SWR };
  50. // function field (encoded in fn if opcode = OP__FN)
  51. enum { FN_SLL=000, __(01), FN_SRL, FN_SRA, FN_SLLV, __(05), FN_SRLV, FN_SRAV };
  52. enum { FN_MFHI=020, FN_MTHI, FN_MFLO, FN_MTLO };
  53. enum { FN_MULT=030, FN_MULTU, FN_DIV, FN_DIVU };
  54. enum { FN_ADD=040, FN_ADDU, FN_SUB, FN_SUBU, FN_AND, FN_OR, FN_XOR, FN_NOR };
  55. enum { FN_JR=010, FN_JALR, FN_MOVZ, FN_MOVN, FN_SYNC=017, FN_SLT=052, FN_SLTU };
  56. // rt field (encoded in rt if opcode = OP__RT)
  57. enum { RT_BLTZ=000, RT_BGEZ, RT_BLTZAL=020, RT_BGEZAL, RT_SYNCI=037 };
  58. #define MIPS_NOP 000 // null operation: SLL r0, r0, #0
  59. // arithmetic/logical
  60. #define MIPS_OP_REG(op, rd, rs, rt) \
  61. MIPS_INSN(OP__FN, rs, rt, rd, _, op) // R-type, SPECIAL
  62. #define MIPS_OP_IMM(op, rt, rs, imm) \
  63. MIPS_INSN(op, rs, rt, _, _, (u16)(imm)) // I-type
  64. // rd = rt OP rs
  65. #define MIPS_ADD_REG(rd, rs, rt) \
  66. MIPS_OP_REG(FN_ADDU, rd, rs, rt)
  67. #define MIPS_SUB_REG(rd, rs, rt) \
  68. MIPS_OP_REG(FN_SUBU, rd, rs, rt)
  69. #define MIPS_NEG_REG(rd, rt) \
  70. MIPS_SUB_REG(rd, Z0, rt)
  71. #define MIPS_XOR_REG(rd, rs, rt) \
  72. MIPS_OP_REG(FN_XOR, rd, rs, rt)
  73. #define MIPS_OR_REG(rd, rs, rt) \
  74. MIPS_OP_REG(FN_OR, rd, rs, rt)
  75. #define MIPS_AND_REG(rd, rs, rt) \
  76. MIPS_OP_REG(FN_AND, rd, rs, rt)
  77. #define MIPS_NOR_REG(rd, rs, rt) \
  78. MIPS_OP_REG(FN_NOR, rd, rs, rt)
  79. #define MIPS_MOVE_REG(rd, rs) \
  80. MIPS_OR_REG(rd, rs, Z0)
  81. #define MIPS_MVN_REG(rd, rs) \
  82. MIPS_NOR_REG(rd, rs, Z0)
  83. // rd = rt SHIFT rs
  84. #define MIPS_LSL_REG(rd, rt, rs) \
  85. MIPS_OP_REG(FN_SLLV, rd, rs, rt)
  86. #define MIPS_LSR_REG(rd, rt, rs) \
  87. MIPS_OP_REG(FN_SRLV, rd, rs, rt)
  88. #define MIPS_ASR_REG(rd, rt, rs) \
  89. MIPS_OP_REG(FN_SRAV, rd, rs, rt)
  90. // rd = (rs < rt)
  91. #define MIPS_SLT_REG(rd, rs, rt) \
  92. MIPS_OP_REG(FN_SLT, rd, rs, rt)
  93. #define MIPS_SLTU_REG(rd, rs, rt) \
  94. MIPS_OP_REG(FN_SLTU, rd, rs, rt)
  95. // rt = rs OP imm16
  96. #define MIPS_ADD_IMM(rt, rs, imm16) \
  97. MIPS_OP_IMM(OP_ADDIU, rt, rs, imm16)
  98. #define MIPS_XOR_IMM(rt, rs, imm16) \
  99. MIPS_OP_IMM(OP_XORI, rt, rs, imm16)
  100. #define MIPS_OR_IMM(rt, rs, imm16) \
  101. MIPS_OP_IMM(OP_ORI, rt, rs, imm16)
  102. #define MIPS_AND_IMM(rt, rs, imm16) \
  103. MIPS_OP_IMM(OP_ANDI, rt, rs, imm16)
  104. // rt = (imm16 << (0|16))
  105. #define MIPS_MOV_IMM(rt, imm16) \
  106. MIPS_OP_IMM(OP_ORI, rt, Z0, imm16)
  107. #define MIPS_MOVT_IMM(rt, imm16) \
  108. MIPS_OP_IMM(OP_LUI, rt, _, imm16)
  109. // rd = rt SHIFT imm5
  110. #define MIPS_LSL_IMM(rd, rt, bits) \
  111. MIPS_INSN(OP__FN, _, rt, rd, bits, FN_SLL)
  112. #define MIPS_LSR_IMM(rd, rt, bits) \
  113. MIPS_INSN(OP__FN, _, rt, rd, bits, FN_SRL)
  114. #define MIPS_ASR_IMM(rd, rt, bits) \
  115. MIPS_INSN(OP__FN, _, rt, rd, bits, FN_SRA)
  116. // rt = (rs < imm16)
  117. #define MIPS_SLT_IMM(rt, rs, imm16) \
  118. MIPS_OP_IMM(OP_SLTI, rt, rs, imm16)
  119. #define MIPS_SLTU_IMM(rt, rs, imm16) \
  120. MIPS_OP_IMM(OP_SLTIU, rt, rs, imm16)
  121. // multiplication
  122. #define MIPS_MULT(rt, rs) \
  123. MIPS_OP_REG(FN_MULT, _, rs, rt)
  124. #define MIPS_MULTU(rt, rs) \
  125. MIPS_OP_REG(FN_MULTU, _, rs, rt)
  126. #define MIPS_MFLO(rd) \
  127. MIPS_OP_REG(FN_MFLO, rd, _, _)
  128. #define MIPS_MFHI(rd) \
  129. MIPS_OP_REG(FN_MFHI, rd, _, _)
  130. // branching
  131. #define MIPS_J(abs26) \
  132. MIPS_INSN(OP_J, _,_,_,_, (abs26) >> 2) // J-type
  133. #define MIPS_JAL(abs26) \
  134. MIPS_INSN(OP_JAL, _,_,_,_, (abs26) >> 2)
  135. #define MIPS_JR(rs) \
  136. MIPS_OP_REG(FN_JR,_,rs,_)
  137. #define MIPS_JALR(rd, rs) \
  138. MIPS_OP_REG(FN_JALR,rd,rs,_)
  139. // conditional branches; no condition code, these compare rs against rt or Z0
  140. #define MIPS_BEQ (OP_BEQ << 5)
  141. #define MIPS_BNE (OP_BNE << 5)
  142. #define MIPS_BLE (OP_BLEZ << 5)
  143. #define MIPS_BGT (OP_BGTZ << 5)
  144. #define MIPS_BLT ((OP__RT << 5)|RT_BLTZ)
  145. #define MIPS_BGE ((OP__RT << 5)|RT_BGEZ)
  146. #define MIPS_BGTL ((OP__RT << 5)|RT_BLTZAL)
  147. #define MIPS_BGEL ((OP__RT << 5)|RT_BGEZAL)
  148. #define MIPS_BCONDZ(cond, rs, offs16) \
  149. MIPS_OP_IMM((cond >> 5), (cond & 0x1f), rs, (offs16) >> 2)
  150. #define MIPS_B(offs16) \
  151. MIPS_BCONDZ(MIPS_BEQ, Z0, offs16)
  152. #define MIPS_BL(offs16) \
  153. MIPS_BCONDZ(MIPS_BGEL, Z0, offs16)
  154. // load/store indexed base
  155. #define MIPS_LW(rt, rs, offs16) \
  156. MIPS_INSN(OP_LW, rs, rt, _,_, (u16)(offs16))
  157. #define MIPS_LH(rt, rs, offs16) \
  158. MIPS_INSN(OP_LH, rs, rt, _,_, (u16)(offs16))
  159. #define MIPS_LB(rt, rs, offs16) \
  160. MIPS_INSN(OP_LB, rs, rt, _,_, (u16)(offs16))
  161. #define MIPS_LHU(rt, rs, offs16) \
  162. MIPS_INSN(OP_LHU, rs, rt, _,_, (u16)(offs16))
  163. #define MIPS_LBU(rt, rs, offs16) \
  164. MIPS_INSN(OP_LBU, rs, rt, _,_, (u16)(offs16))
  165. #define MIPS_SW(rt, rs, offs16) \
  166. MIPS_INSN(OP_SW, rs, rt, _,_, (u16)(offs16))
  167. #define MIPS_SH(rt, rs, offs16) \
  168. MIPS_INSN(OP_SH, rs, rt, _,_, (u16)(offs16))
  169. #define MIPS_SB(rt, rs, offs16) \
  170. MIPS_INSN(OP_SB, rs, rt, _,_, (u16)(offs16))
  171. // XXX: tcache_ptr type for SVP and SH2 compilers differs..
  172. #define EMIT_PTR(ptr, x) \
  173. do { \
  174. *(u32 *)(ptr) = x; \
  175. ptr = (void *)((u8 *)(ptr) + sizeof(u32)); \
  176. } while (0)
  177. // FIFO for 2 instructions, for delay slot handling
  178. u32 emith_last_insns[2] = { -1,-1 };
  179. int emith_last_idx;
  180. #define EMIT_PUSHOP() \
  181. do { \
  182. emith_last_idx ^= 1; \
  183. if (emith_last_insns[emith_last_idx] != -1) \
  184. EMIT_PTR(tcache_ptr, emith_last_insns[emith_last_idx]);\
  185. emith_last_insns[emith_last_idx] = -1; \
  186. } while (0)
  187. #define EMIT(op) \
  188. do { \
  189. EMIT_PUSHOP(); \
  190. emith_last_insns[emith_last_idx] = op; \
  191. COUNT_OP; \
  192. } while (0)
  193. #define emith_flush() \
  194. do { \
  195. int i; for (i = 0; i < 2; i++) EMIT_PUSHOP(); \
  196. } while (0)
  197. #define emith_insn_ptr() (u8 *)((u32 *)tcache_ptr + \
  198. (emith_last_insns[0] != -1) + (emith_last_insns[1] != -1))
  199. // delay slot stuff
  200. static int emith_is_j(u32 op) // J, JAL
  201. { return ((op>>26) & 076) == OP_J; }
  202. static int emith_is_jr(u32 op) // JR, JALR
  203. { return (op>>26) == OP__FN && (op & 076) == FN_JR; }
  204. static int emith_is_b(u32 op) // B
  205. { return ((op>>26) & 074) == OP_BEQ ||
  206. ((op>>26) == OP__RT && ((op>>16) & 036) == RT_BLTZ); }
  207. // register usage for dependency evaluation XXX better do this as in emit_arm?
  208. static uint64_t emith_has_rs[3] = // OP__FN, OP__RT, others
  209. { 0x00fffffffffa0ff0ULL, 0x000fff0fUL, 0xffffffff0f007f30ULL };
  210. static uint64_t emith_has_rt[3] = // OP__FN, OP__RT, others
  211. { 0xff00fffffff00cffULL, 0x00000000UL, 0x8000ff0000000030ULL };
  212. static uint64_t emith_has_rd[3] = // OP__FN, OP__RT, others (rt instead of rd)
  213. { 0xff00fffffff50fffULL, 0x00000000UL, 0x119100ff0f00ff00ULL };
  214. #define emith_has_(rx,ix,op,sa,m) \
  215. (emith_has_##rx[ix] & (1ULL << (((op)>>(sa)) & (m))))
  216. static int emith_rs(u32 op)
  217. { if ((op>>26) == OP__FN)
  218. return emith_has_(rs,0,op, 0,0x3f) ? (op>>21)&0x1f : 0;
  219. if ((op>>26) == OP__RT)
  220. return emith_has_(rs,1,op,16,0x1f) ? (op>>21)&0x1f : 0;
  221. return emith_has_(rs,2,op,26,0x3f) ? (op>>21)&0x1f : 0;
  222. }
  223. static int emith_rt(u32 op)
  224. { if ((op>>26) == OP__FN)
  225. return emith_has_(rt,0,op, 0,0x3f) ? (op>>16)&0x1f : 0;
  226. if ((op>>26) == OP__RT)
  227. return 0;
  228. return emith_has_(rt,2,op,26,0x3f) ? (op>>16)&0x1f : 0;
  229. }
  230. static int emith_rd(u32 op)
  231. { if ((op>>26) == OP__FN)
  232. return emith_has_(rd,0,op, 0,0x3f) ? (op>>11)&0x1f :-1;
  233. if ((op>>26) == OP__RT)
  234. return -1;
  235. return emith_has_(rd,2,op,26,0x3f) ? (op>>16)&0x1f :-1;
  236. }
  237. static int emith_b_isswap(u32 bop, u32 lop)
  238. {
  239. if (emith_is_j(bop))
  240. return bop;
  241. else if (emith_is_jr(bop) && emith_rd(lop) != emith_rs(bop))
  242. return bop;
  243. else if (emith_is_b(bop) && emith_rd(lop) != emith_rs(bop))
  244. if ((bop & 0xffff) != 0x7fff) // displacement overflow?
  245. return (bop & 0xffff0000) | ((bop & 0xffff)+1);
  246. return 0;
  247. }
  248. // emit branch, trying to fill the delay slot with one of the last insns
  249. static void *emith_branch(u32 op)
  250. {
  251. int idx = emith_last_idx;
  252. u32 op1 = emith_last_insns[idx], op2 = emith_last_insns[idx^1];
  253. u32 bop = 0;
  254. void *bp;
  255. // check last insn (op1)
  256. if (op1 != -1 && op1)
  257. bop = emith_b_isswap(op, op1);
  258. // if not, check older insn (op2); mustn't interact with op1 to overtake
  259. if (!bop && op2 != -1 && op2 && emith_rd(op1) != emith_rd(op2) &&
  260. emith_rs(op1) != emith_rd(op2) && emith_rt(op1) != emith_rd(op2) &&
  261. emith_rs(op2) != emith_rd(op1) && emith_rt(op2) != emith_rd(op1)) {
  262. idx ^= 1;
  263. bop = emith_b_isswap(op, op2);
  264. }
  265. if (bop) { // can swap
  266. if (emith_last_insns[idx^1] != -1)
  267. EMIT_PTR(tcache_ptr, emith_last_insns[idx^1]);
  268. bp = tcache_ptr;
  269. EMIT_PTR(tcache_ptr, bop); COUNT_OP;
  270. EMIT_PTR(tcache_ptr, emith_last_insns[idx]);
  271. emith_last_insns[0] = emith_last_insns[1] = -1;
  272. } else { // can't swap
  273. emith_flush();
  274. bp = tcache_ptr;
  275. EMIT_PTR(tcache_ptr, op); COUNT_OP;
  276. EMIT_PTR(tcache_ptr, MIPS_NOP); COUNT_OP;
  277. }
  278. return bp;
  279. }
  280. // if-then-else conditional execution helpers
  281. #define JMP_POS(ptr) \
  282. ptr = emith_branch(MIPS_BCONDZ(cond_m, cond_r, 0));
  283. #define JMP_EMIT(cond, ptr) { \
  284. u32 val_ = emith_insn_ptr() - (u8 *)(ptr) - 4; \
  285. EMIT_PTR(ptr, MIPS_BCONDZ(cond_m, cond_r, val_ & 0x0003ffff)); \
  286. emith_flush(); /* NO delay slot handling across jump targets */ \
  287. }
  288. #define JMP_EMIT_NC(ptr) { \
  289. u32 val_ = emith_insn_ptr() - (u8 *)(ptr) - 4; \
  290. EMIT_PTR(ptr, MIPS_B(val_ & 0x0003ffff)); \
  291. emith_flush(); \
  292. }
  293. #define EMITH_JMP_START(cond) { \
  294. int cond_r, cond_m = emith_cond_check(cond, &cond_r); \
  295. u8 *cond_ptr; \
  296. JMP_POS(cond_ptr)
  297. #define EMITH_JMP_END(cond) \
  298. JMP_EMIT(cond, cond_ptr); \
  299. }
  300. #define EMITH_JMP3_START(cond) { \
  301. int cond_r, cond_m = emith_cond_check(cond, &cond_r); \
  302. u8 *cond_ptr, *else_ptr; \
  303. JMP_POS(cond_ptr)
  304. #define EMITH_JMP3_MID(cond) \
  305. JMP_POS(else_ptr); \
  306. JMP_EMIT(cond, cond_ptr);
  307. #define EMITH_JMP3_END() \
  308. JMP_EMIT_NC(else_ptr); \
  309. }
  310. // "simple" jump (no more then a few insns)
  311. // ARM32 will use conditional instructions here
  312. #define EMITH_SJMP_START EMITH_JMP_START
  313. #define EMITH_SJMP_END EMITH_JMP_END
  314. #define EMITH_SJMP3_START EMITH_JMP3_START
  315. #define EMITH_SJMP3_MID EMITH_JMP3_MID
  316. #define EMITH_SJMP3_END EMITH_JMP3_END
  317. #define EMITH_SJMP2_START(cond) \
  318. EMITH_SJMP3_START(cond)
  319. #define EMITH_SJMP2_MID(cond) \
  320. EMITH_SJMP3_MID(cond)
  321. #define EMITH_SJMP2_END(cond) \
  322. EMITH_SJMP3_END()
  323. // flag register emulation. this is modelled after arm/x86.
  324. // the FNZ register stores the result of the last flag setting operation for
  325. // N and Z flag, used for EQ,NE,MI,PL branches.
  326. // the FC register stores the C flag (used for HI,HS,LO,LS,CC,CS).
  327. // the FV register stores information for V flag calculation (used for
  328. // GT,GE,LT,LE,VC,VS). V flag is costly and only fully calculated when needed.
  329. // the core registers may be temp registers, since the condition after calls
  330. // is undefined anyway.
  331. // flag emulation creates 2 (ie cmp #0/beq) up to 9 (ie adcf/ble) extra insns.
  332. // flag handling shortcuts may reduce this by 1-4 insns, see emith_cond_check()
  333. int emith_flg_rs, emith_flg_rt; // registers used in FNZ=rs-rt (aka cmp_r_r)
  334. int emith_flg_noV; // V flag known not to be set
  335. // store minimal cc information: rd, rt^rs, carry
  336. // NB: the result *must* first go to FNZ, in case rd == rs or rd == rt.
  337. // NB: for adcf and sbcf, carry-in must be dealt with separately (see there)
  338. static void emith_set_arith_flags(int rd, int rt, int rs, s32 imm, int sub)
  339. {
  340. if (sub && rd == FNZ && rt > AT && rs > AT) // is this cmp_r_r?
  341. emith_flg_rs = rs, emith_flg_rt = rt;
  342. else emith_flg_rs = emith_flg_rt = 0;
  343. if (sub) // C = sub:rt<rd, add:rd<rt
  344. EMIT(MIPS_SLTU_REG(FC, rt, FNZ));
  345. else EMIT(MIPS_SLTU_REG(FC, FNZ, rt));// C in FC, bit 0
  346. emith_flg_noV = 0;
  347. if (rs > 0) // Nt^Ns
  348. EMIT(MIPS_XOR_REG(FV, rt, rs));
  349. else if (imm < 0)
  350. EMIT(MIPS_NOR_REG(FV, rt, Z0));
  351. else if (imm > 0)
  352. EMIT(MIPS_OR_REG(FV, rt, Z0)); // Nt^Ns in FV, bit 31
  353. else emith_flg_noV = 1; // imm #0, never overflows
  354. // full V = Nd^Nt^Ns^C calculation is deferred until really needed
  355. if (rd != FNZ)
  356. EMIT(MIPS_MOVE_REG(rd, FNZ)); // N,Z via result value in FNZ
  357. }
  358. // data processing, register
  359. #define emith_move_r_r_ptr(d, s) \
  360. EMIT(MIPS_MOVE_REG(d, s))
  361. #define emith_move_r_r_ptr_c(cond, d, s) \
  362. emith_move_r_r_ptr(d, s)
  363. #define emith_move_r_r(d, s) \
  364. emith_move_r_r_ptr(d, s)
  365. #define emith_move_r_r_c(cond, d, s) \
  366. emith_move_r_r(d, s)
  367. #define emith_mvn_r_r(d, s) \
  368. EMIT(MIPS_MVN_REG(d, s))
  369. #define emith_add_r_r_r_lsl_ptr(d, s1, s2, simm) do { \
  370. if (simm) { \
  371. EMIT(MIPS_LSL_IMM(AT, s2, simm)); \
  372. EMIT(MIPS_ADD_REG(d, s1, AT)); \
  373. } else EMIT(MIPS_ADD_REG(d, s1, s2)); \
  374. } while (0)
  375. #define emith_add_r_r_r_lsl(d, s1, s2, simm) \
  376. emith_add_r_r_r_lsl_ptr(d, s1, s2, simm)
  377. #define emith_add_r_r_r_lsr(d, s1, s2, simm) do { \
  378. if (simm) { \
  379. EMIT(MIPS_LSR_IMM(AT, s2, simm)); \
  380. EMIT(MIPS_ADD_REG(d, s1, AT)); \
  381. } else EMIT(MIPS_ADD_REG(d, s1, s2)); \
  382. } while (0)
  383. #define emith_addf_r_r_r_lsl(d, s1, s2, simm) do { \
  384. if (simm) { \
  385. EMIT(MIPS_LSL_IMM(AT, s2, simm)); \
  386. EMIT(MIPS_ADD_REG(FNZ, s1, AT)); \
  387. emith_set_arith_flags(d, s1, AT, 0, 0); \
  388. } else { \
  389. EMIT(MIPS_ADD_REG(FNZ, s1, s2)); \
  390. emith_set_arith_flags(d, s1, s2, 0, 0); \
  391. } \
  392. } while (0)
  393. #define emith_addf_r_r_r_lsr(d, s1, s2, simm) do { \
  394. if (simm) { \
  395. EMIT(MIPS_LSR_IMM(AT, s2, simm)); \
  396. EMIT(MIPS_ADD_REG(FNZ, s1, AT)); \
  397. emith_set_arith_flags(d, s1, AT, 0, 0); \
  398. } else { \
  399. EMIT(MIPS_ADD_REG(FNZ, s1, s2)); \
  400. emith_set_arith_flags(d, s1, s2, 0, 0); \
  401. } \
  402. } while (0)
  403. #define emith_sub_r_r_r_lsl(d, s1, s2, simm) do { \
  404. if (simm) { \
  405. EMIT(MIPS_LSL_IMM(AT, s2, simm)); \
  406. EMIT(MIPS_SUB_REG(d, s1, AT)); \
  407. } else EMIT(MIPS_SUB_REG(d, s1, s2)); \
  408. } while (0)
  409. #define emith_subf_r_r_r_lsl(d, s1, s2, simm) do { \
  410. if (simm) { \
  411. EMIT(MIPS_LSL_IMM(AT, s2, simm)); \
  412. EMIT(MIPS_SUB_REG(FNZ, s1, AT)); \
  413. emith_set_arith_flags(d, s1, AT, 0, 1); \
  414. } else { \
  415. EMIT(MIPS_SUB_REG(FNZ, s1, s2)); \
  416. emith_set_arith_flags(d, s1, s2, 0, 1); \
  417. } \
  418. } while (0)
  419. #define emith_or_r_r_r_lsl(d, s1, s2, simm) do { \
  420. if (simm) { \
  421. EMIT(MIPS_LSL_IMM(AT, s2, simm)); \
  422. EMIT(MIPS_OR_REG(d, s1, AT)); \
  423. } else EMIT(MIPS_OR_REG(d, s1, s2)); \
  424. } while (0)
  425. #define emith_eor_r_r_r_lsl(d, s1, s2, simm) do { \
  426. if (simm) { \
  427. EMIT(MIPS_LSL_IMM(AT, s2, simm)); \
  428. EMIT(MIPS_XOR_REG(d, s1, AT)); \
  429. } else EMIT(MIPS_XOR_REG(d, s1, s2)); \
  430. } while (0)
  431. #define emith_eor_r_r_r_lsr(d, s1, s2, simm) do { \
  432. if (simm) { \
  433. EMIT(MIPS_LSR_IMM(AT, s2, simm)); \
  434. EMIT(MIPS_XOR_REG(d, s1, AT)); \
  435. } else EMIT(MIPS_XOR_REG(d, s1, s2)); \
  436. } while (0)
  437. #define emith_and_r_r_r_lsl(d, s1, s2, simm) do { \
  438. if (simm) { \
  439. EMIT(MIPS_LSL_IMM(AT, s2, simm)); \
  440. EMIT(MIPS_AND_REG(d, s1, AT)); \
  441. } else EMIT(MIPS_AND_REG(d, s1, s2)); \
  442. } while (0)
  443. #define emith_or_r_r_lsl(d, s, lslimm) \
  444. emith_or_r_r_r_lsl(d, d, s, lslimm)
  445. #define emith_eor_r_r_lsr(d, s, lsrimm) \
  446. emith_eor_r_r_r_lsr(d, d, s, lsrimm)
  447. #define emith_add_r_r_r(d, s1, s2) \
  448. emith_add_r_r_r_lsl(d, s1, s2, 0)
  449. #define emith_addf_r_r_r(d, s1, s2) \
  450. emith_addf_r_r_r_lsl(d, s1, s2, 0)
  451. #define emith_sub_r_r_r(d, s1, s2) \
  452. emith_sub_r_r_r_lsl(d, s1, s2, 0)
  453. #define emith_subf_r_r_r(d, s1, s2) \
  454. emith_subf_r_r_r_lsl(d, s1, s2, 0)
  455. #define emith_or_r_r_r(d, s1, s2) \
  456. emith_or_r_r_r_lsl(d, s1, s2, 0)
  457. #define emith_eor_r_r_r(d, s1, s2) \
  458. emith_eor_r_r_r_lsl(d, s1, s2, 0)
  459. #define emith_and_r_r_r(d, s1, s2) \
  460. emith_and_r_r_r_lsl(d, s1, s2, 0)
  461. #define emith_add_r_r_ptr(d, s) \
  462. emith_add_r_r_r_lsl_ptr(d, d, s, 0)
  463. #define emith_add_r_r(d, s) \
  464. emith_add_r_r_r(d, d, s)
  465. #define emith_sub_r_r(d, s) \
  466. emith_sub_r_r_r(d, d, s)
  467. #define emith_neg_r_r(d, s) \
  468. EMIT(MIPS_NEG_REG(d, s))
  469. #define emith_adc_r_r_r(d, s1, s2) do { \
  470. emith_add_r_r_r(AT, s1, FC); \
  471. emith_add_r_r_r(d, AT, s2); \
  472. } while (0)
  473. #define emith_adc_r_r(d, s) \
  474. emith_adc_r_r_r(d, d, s)
  475. // NB: the incoming C can cause its own outgoing C if s2+C=0 (or s1+C=0 FWIW)
  476. // moreover, s2 is 0 if there is C, so no other C can be generated.
  477. #define emith_adcf_r_r_r(d, s1, s2) do { \
  478. emith_add_r_r_r(FNZ, s2, FC); \
  479. EMIT(MIPS_SLTU_REG(AT, FNZ, FC)); \
  480. emith_add_r_r_r(FNZ, s1, FNZ); \
  481. emith_set_arith_flags(d, s1, s2, 0, 0); \
  482. emith_or_r_r(FC, AT); \
  483. } while (0)
  484. #define emith_sbcf_r_r_r(d, s1, s2) do { \
  485. emith_add_r_r_r(FNZ, s2, FC); \
  486. EMIT(MIPS_SLTU_REG(AT, FNZ, FC)); \
  487. emith_sub_r_r_r(FNZ, s1, FNZ); \
  488. emith_set_arith_flags(d, s1, s2, 0, 1); \
  489. emith_or_r_r(FC, AT); \
  490. } while (0)
  491. #define emith_and_r_r(d, s) \
  492. emith_and_r_r_r(d, d, s)
  493. #define emith_and_r_r_c(cond, d, s) \
  494. emith_and_r_r(d, s)
  495. #define emith_or_r_r(d, s) \
  496. emith_or_r_r_r(d, d, s)
  497. #define emith_eor_r_r(d, s) \
  498. emith_eor_r_r_r(d, d, s)
  499. #define emith_tst_r_r_ptr(d, s) \
  500. emith_and_r_r_r(FNZ, d, s)
  501. #define emith_tst_r_r(d, s) \
  502. emith_tst_r_r_ptr(d, s)
  503. #define emith_teq_r_r(d, s) \
  504. emith_eor_r_r_r(FNZ, d, s)
  505. #define emith_cmp_r_r(d, s) \
  506. emith_subf_r_r_r(FNZ, d, s)
  507. #define emith_addf_r_r(d, s) \
  508. emith_addf_r_r_r(d, d, s)
  509. #define emith_subf_r_r(d, s) \
  510. emith_subf_r_r_r(d, d, s)
  511. #define emith_adcf_r_r(d, s) \
  512. emith_adcf_r_r_r(d, d, s)
  513. #define emith_sbcf_r_r(d, s) \
  514. emith_sbcf_r_r_r(d, d, s)
  515. #define emith_negcf_r_r(d, s) \
  516. emith_sbcf_r_r_r(d, Z0, s)
  517. // move immediate
  518. static void emith_move_imm(int r, uintptr_t imm)
  519. {
  520. if ((s16)imm != imm) {
  521. int s = Z0;
  522. if (imm >> 16) {
  523. EMIT(MIPS_MOVT_IMM(r, imm >> 16));
  524. s = r;
  525. }
  526. if ((u16)imm)
  527. EMIT(MIPS_OR_IMM(r, s, (u16)imm));
  528. } else
  529. EMIT(MIPS_ADD_IMM(r, Z0, imm));
  530. }
  531. #define emith_move_r_ptr_imm(r, imm) \
  532. emith_move_imm(r, (uintptr_t)(imm))
  533. #define emith_move_r_imm(r, imm) \
  534. emith_move_imm(r, (u32)(imm))
  535. #define emith_move_r_imm_c(cond, r, imm) \
  536. emith_move_r_imm(r, imm)
  537. // arithmetic, immediate
  538. static void emith_arith_imm(int op, int rd, int rs, u32 imm)
  539. {
  540. if ((s16)imm != imm) {
  541. emith_move_r_imm(AT, imm);
  542. EMIT(MIPS_OP_REG(FN_ADD + (op-OP_ADDI), rd, rs, AT));
  543. } else if (imm || rd != rs)
  544. EMIT(MIPS_OP_IMM(op, rd, rs, imm));
  545. }
  546. #define emith_add_r_imm(r, imm) \
  547. emith_add_r_r_imm(r, r, imm)
  548. #define emith_add_r_imm_c(cond, r, imm) \
  549. emith_add_r_imm(r, imm)
  550. #define emith_addf_r_imm(r, imm) \
  551. emith_addf_r_r_imm(r, imm)
  552. #define emith_sub_r_imm(r, imm) \
  553. emith_sub_r_r_imm(r, r, imm)
  554. #define emith_sub_r_imm_c(cond, r, imm) \
  555. emith_sub_r_imm(r, imm)
  556. #define emith_subf_r_imm(r, imm) \
  557. emith_subf_r_r_imm(r, r, imm)
  558. #define emith_adc_r_imm(r, imm) \
  559. emith_adc_r_r_imm(r, r, imm);
  560. #define emith_adcf_r_imm(r, imm) \
  561. emith_adcf_r_r_imm(r, r, imm)
  562. #define emith_cmp_r_imm(r, imm) \
  563. emith_subf_r_r_imm(FNZ, r, (s16)imm)
  564. #define emith_add_r_r_ptr_imm(d, s, imm) \
  565. emith_arith_imm(OP_ADDIU, d, s, imm)
  566. #define emith_add_r_r_imm(d, s, imm) \
  567. emith_add_r_r_ptr_imm(d, s, imm)
  568. #define emith_addf_r_r_imm(d, s, imm) do { \
  569. emith_add_r_r_imm(FNZ, s, imm); \
  570. emith_set_arith_flags(d, s, 0, imm, 0); \
  571. } while (0)
  572. #define emith_adc_r_r_imm(d, s, imm) do { \
  573. emith_add_r_r_r(AT, s, FC); \
  574. emith_add_r_r_imm(d, AT, imm); \
  575. } while (0)
  576. #define emith_adcf_r_r_imm(d, s, imm) do { \
  577. emith_add_r_r_r(FNZ, s, FC); \
  578. EMIT(MIPS_SLTU_REG(AT, FNZ, FC)); \
  579. emith_add_r_r_imm(FNZ, FNZ, imm); \
  580. emith_set_arith_flags(d, s, 0, imm, 0); \
  581. emith_or_r_r(FC, AT); \
  582. } while (0)
  583. // NB: no SUBI in MIPS II, since ADDI takes a signed imm
  584. #define emith_sub_r_r_imm(d, s, imm) \
  585. emith_add_r_r_imm(d, s, -(imm))
  586. #define emith_sub_r_r_imm_c(cond, d, s, imm) \
  587. emith_sub_r_r_imm(d, s, imm)
  588. #define emith_subf_r_r_imm(d, s, imm) do { \
  589. emith_sub_r_r_imm(FNZ, s, imm); \
  590. emith_set_arith_flags(d, s, 0, imm, 1); \
  591. } while (0)
  592. // logical, immediate
  593. static void emith_log_imm(int op, int rd, int rs, u32 imm)
  594. {
  595. if (imm >> 16) {
  596. emith_move_r_imm(AT, imm);
  597. EMIT(MIPS_OP_REG(FN_AND + (op-OP_ANDI), rd, rs, AT));
  598. } else if (op == OP_ANDI || imm || rd != rs)
  599. EMIT(MIPS_OP_IMM(op, rd, rs, imm));
  600. }
  601. #define emith_and_r_imm(r, imm) \
  602. emith_log_imm(OP_ANDI, r, r, imm)
  603. #define emith_or_r_imm(r, imm) \
  604. emith_log_imm(OP_ORI, r, r, imm)
  605. #define emith_or_r_imm_c(cond, r, imm) \
  606. emith_or_r_imm(r, imm)
  607. #define emith_eor_r_imm_ptr(r, imm) \
  608. emith_log_imm(OP_XORI, r, r, imm)
  609. #define emith_eor_r_imm_ptr_c(cond, r, imm) \
  610. emith_eor_r_imm_ptr(r, imm)
  611. #define emith_eor_r_imm(r, imm) \
  612. emith_eor_r_imm_ptr(r, imm)
  613. #define emith_eor_r_imm_c(cond, r, imm) \
  614. emith_eor_r_imm(r, imm)
  615. /* NB: BIC #imm not available in MIPS; use AND #~imm instead */
  616. #define emith_bic_r_imm(r, imm) \
  617. emith_log_imm(OP_ANDI, r, r, ~(imm))
  618. #define emith_bic_r_imm_c(cond, r, imm) \
  619. emith_bic_r_imm(r, imm)
  620. #define emith_tst_r_imm(r, imm) \
  621. emith_log_imm(OP_ANDI, FNZ, r, imm)
  622. #define emith_tst_r_imm_c(cond, r, imm) \
  623. emith_tst_r_imm(r, imm)
  624. #define emith_and_r_r_imm(d, s, imm) \
  625. emith_log_imm(OP_ANDI, d, s, imm)
  626. #define emith_or_r_r_imm(d, s, imm) \
  627. emith_log_imm(OP_ORI, d, s, imm)
  628. #define emith_eor_r_r_imm(d, s, imm) \
  629. emith_log_imm(OP_XORI, d, s, imm)
  630. // shift
  631. #define emith_lsl(d, s, cnt) \
  632. EMIT(MIPS_LSL_IMM(d, s, cnt))
  633. #define emith_lsr(d, s, cnt) \
  634. EMIT(MIPS_LSR_IMM(d, s, cnt))
  635. #define emith_asr(d, s, cnt) \
  636. EMIT(MIPS_ASR_IMM(d, s, cnt))
  637. // NB: mips32r2 has ROT (SLR with R bit set)
  638. #define emith_ror(d, s, cnt) do { \
  639. EMIT(MIPS_LSL_IMM(AT, s, 32-(cnt))); \
  640. EMIT(MIPS_LSR_IMM(d, s, cnt)); \
  641. EMIT(MIPS_OR_REG(d, d, AT)); \
  642. } while (0)
  643. #define emith_ror_c(cond, d, s, cnt) \
  644. emith_ror(d, s, cnt)
  645. #define emith_rol(d, s, cnt) do { \
  646. EMIT(MIPS_LSR_IMM(AT, s, 32-(cnt))); \
  647. EMIT(MIPS_LSL_IMM(d, s, cnt)); \
  648. EMIT(MIPS_OR_REG(d, d, AT)); \
  649. } while (0)
  650. // NB: all flag setting shifts make V undefined
  651. // NB: mips32r2 has EXT (useful for extracting C)
  652. #define emith_lslf(d, s, cnt) do { \
  653. int _s = s; \
  654. if ((cnt) > 1) { \
  655. emith_lsl(d, s, cnt-1); \
  656. _s = d; \
  657. } \
  658. if ((cnt) > 0) { \
  659. emith_lsr(FC, _s, 31); \
  660. emith_lsl(d, _s, 1); \
  661. } \
  662. emith_move_r_r(FNZ, d); \
  663. } while (0)
  664. #define emith_lsrf(d, s, cnt) do { \
  665. int _s = s; \
  666. if ((cnt) > 1) { \
  667. emith_lsr(d, s, cnt-1); \
  668. _s = d; \
  669. } \
  670. if ((cnt) > 0) { \
  671. emith_and_r_r_imm(FC, _s, 1); \
  672. emith_lsr(d, _s, 1); \
  673. } \
  674. emith_move_r_r(FNZ, d); \
  675. } while (0)
  676. #define emith_asrf(d, s, cnt) do { \
  677. int _s = s; \
  678. if ((cnt) > 1) { \
  679. emith_asr(d, s, cnt-1); \
  680. _s = d; \
  681. } \
  682. if ((cnt) > 0) { \
  683. emith_and_r_r_imm(FC, _s, 1); \
  684. emith_asr(d, _s, 1); \
  685. } \
  686. emith_move_r_r(FNZ, d); \
  687. } while (0)
  688. #define emith_rolf(d, s, cnt) do { \
  689. emith_rol(d, s, cnt); \
  690. emith_and_r_r_imm(FC, d, 1); \
  691. emith_move_r_r(FNZ, d); \
  692. } while (0)
  693. #define emith_rorf(d, s, cnt) do { \
  694. emith_ror(d, s, cnt); \
  695. emith_lsr(FC, d, 31); \
  696. emith_move_r_r(FNZ, d); \
  697. } while (0)
  698. #define emith_rolcf(d) do { \
  699. emith_lsr(AT, d, 31); \
  700. emith_lsl(d, d, 1); \
  701. emith_or_r_r(d, FC); \
  702. emith_move_r_r(FC, AT); \
  703. emith_move_r_r(FNZ, d); \
  704. } while (0)
  705. #define emith_rorcf(d) do { \
  706. emith_and_r_r_imm(AT, d, 1); \
  707. emith_lsr(d, d, 1); \
  708. emith_lsl(FC, FC, 31); \
  709. emith_or_r_r(d, FC); \
  710. emith_move_r_r(FC, AT); \
  711. emith_move_r_r(FNZ, d); \
  712. } while (0)
  713. // signed/unsigned extend
  714. // NB: mips32r2 has EXT and INS
  715. #define emith_clear_msb(d, s, count) /* bits to clear */ do { \
  716. u32 t; \
  717. if ((count) >= 16) { \
  718. t = (count) - 16; \
  719. t = 0xffff >> t; \
  720. emith_and_r_r_imm(d, s, t); \
  721. } else { \
  722. emith_lsl(d, s, count); \
  723. emith_lsr(d, d, count); \
  724. } \
  725. } while (0)
  726. #define emith_clear_msb_c(cond, d, s, count) \
  727. emith_clear_msb(d, s, count)
  728. // NB: mips32r2 has SE[BH]H
  729. #define emith_sext(d, s, count) /* bits to keep */ do { \
  730. emith_lsl(d, s, 32-(count)); \
  731. emith_asr(d, d, 32-(count)); \
  732. } while (0)
  733. // multiply Rd = Rn*Rm (+ Ra); NB: next 2 insns after MFLO/MFHI mustn't be MULT
  734. static u8 *last_lohi;
  735. static void emith_lohi_nops(void)
  736. {
  737. u32 d;
  738. while ((d = emith_insn_ptr() - last_lohi) < 8 && d >= 0) EMIT(MIPS_NOP);
  739. }
  740. #define emith_mul(d, s1, s2) do { \
  741. emith_lohi_nops(); \
  742. EMIT(MIPS_MULTU(s1, s2)); \
  743. EMIT(MIPS_MFLO(d)); \
  744. last_lohi = emith_insn_ptr(); \
  745. } while (0)
  746. #define emith_mul_u64(dlo, dhi, s1, s2) do { \
  747. emith_lohi_nops(); \
  748. EMIT(MIPS_MULTU(s1, s2)); \
  749. EMIT(MIPS_MFLO(dlo)); \
  750. EMIT(MIPS_MFHI(dhi)); \
  751. last_lohi = emith_insn_ptr(); \
  752. } while (0)
  753. #define emith_mul_s64(dlo, dhi, s1, s2) do { \
  754. emith_lohi_nops(); \
  755. EMIT(MIPS_MULT(s1, s2)); \
  756. EMIT(MIPS_MFLO(dlo)); \
  757. EMIT(MIPS_MFHI(dhi)); \
  758. last_lohi = emith_insn_ptr(); \
  759. } while (0)
  760. #define emith_mula_s64(dlo, dhi, s1, s2) do { \
  761. int t_ = rcache_get_tmp(); \
  762. emith_lohi_nops(); \
  763. EMIT(MIPS_MULT(s1, s2)); \
  764. EMIT(MIPS_MFLO(AT)); \
  765. emith_add_r_r(dlo, AT); \
  766. EMIT(MIPS_SLTU_REG(t_, dlo, AT)); \
  767. EMIT(MIPS_MFHI(AT)); \
  768. last_lohi = emith_insn_ptr(); \
  769. emith_add_r_r(dhi, AT); \
  770. emith_add_r_r(dhi, t_); \
  771. rcache_free_tmp(t_); \
  772. } while (0)
  773. #define emith_mula_s64_c(cond, dlo, dhi, s1, s2) \
  774. emith_mula_s64(dlo, dhi, s1, s2)
  775. // load/store. offs has 16 bits signed, which is currently sufficient
  776. #define emith_read_r_r_offs_ptr(r, rs, offs) \
  777. EMIT(MIPS_LW(r, rs, offs))
  778. #define emith_read_r_r_offs_ptr_c(cond, r, rs, offs) \
  779. emith_read_r_r_offs_ptr(r, rs, offs)
  780. #define emith_read_r_r_offs(r, rs, offs) \
  781. emith_read_r_r_offs_ptr(r, rs, offs)
  782. #define emith_read_r_r_offs_c(cond, r, rs, offs) \
  783. emith_read_r_r_offs(r, rs, offs)
  784. #define emith_read_r_r_r_ptr(r, rs, rm) do { \
  785. emith_add_r_r_r(AT, rs, rm); \
  786. EMIT(MIPS_LW(r, AT, 0)); \
  787. } while (0)
  788. #define emith_read_r_r_r(r, rs, rm) \
  789. emith_read_r_r_r_ptr(r, rs, rm)
  790. #define emith_read_r_r_r_c(cond, r, rs, rm) \
  791. emith_read_r_r_r(r, rs, rm)
  792. #define emith_read_r_r_r_ptr_wb(r, rs, rm) do { \
  793. emith_add_r_r_r(rs, rs, rm); \
  794. EMIT(MIPS_LW(r, rs, 0)); \
  795. } while (0)
  796. #define emith_read_r_r_r_wb(r, rs, rm) \
  797. emith_read_r_r_r_ptr_wb(r, rs, rm)
  798. #define emith_read8_r_r_offs(r, rs, offs) \
  799. EMIT(MIPS_LBU(r, rs, offs))
  800. #define emith_read8_r_r_offs_c(cond, r, rs, offs) \
  801. emith_read8_r_r_offs(r, rs, offs)
  802. #define emith_read8_r_r_r(r, rs, rm) do { \
  803. emith_add_r_r_r(AT, rs, rm); \
  804. EMIT(MIPS_LBU(r, AT, 0)); \
  805. } while (0)
  806. #define emith_read8_r_r_r_c(cond, r, rs, rm) \
  807. emith_read8_r_r_r(r, rs, rm)
  808. #define emith_read16_r_r_offs(r, rs, offs) \
  809. EMIT(MIPS_LHU(r, rs, offs))
  810. #define emith_read16_r_r_offs_c(cond, r, rs, offs) \
  811. emith_read16_r_r_offs(r, rs, offs)
  812. #define emith_read16_r_r_r(r, rs, rm) do { \
  813. emith_add_r_r_r(AT, rs, rm); \
  814. EMIT(MIPS_LHU(r, AT, 0)); \
  815. } while (0)
  816. #define emith_read16_r_r_r_c(cond, r, rs, rm) \
  817. emith_read16_r_r_r(r, rs, rm)
  818. #define emith_read8s_r_r_offs(r, rs, offs) \
  819. EMIT(MIPS_LB(r, rs, offs))
  820. #define emith_read8s_r_r_offs_c(cond, r, rs, offs) \
  821. emith_read8s_r_r_offs(r, rs, offs)
  822. #define emith_read8s_r_r_r(r, rs, rm) do { \
  823. emith_add_r_r_r(AT, rs, rm); \
  824. EMIT(MIPS_LB(r, AT, 0)); \
  825. } while (0)
  826. #define emith_read8s_r_r_r_c(cond, r, rs, rm) \
  827. emith_read8s_r_r_r(r, rs, rm)
  828. #define emith_read16s_r_r_offs(r, rs, offs) \
  829. EMIT(MIPS_LH(r, rs, offs))
  830. #define emith_read16s_r_r_offs_c(cond, r, rs, offs) \
  831. emith_read16s_r_r_offs(r, rs, offs)
  832. #define emith_read16s_r_r_r(r, rs, rm) do { \
  833. emith_add_r_r_r(AT, rs, rm); \
  834. EMIT(MIPS_LH(r, AT, 0)); \
  835. } while (0)
  836. #define emith_read16s_r_r_r_c(cond, r, rs, rm) \
  837. emith_read16s_r_r_r(r, rs, rm)
  838. #define emith_write_r_r_offs_ptr(r, rs, offs) \
  839. EMIT(MIPS_SW(r, rs, offs))
  840. #define emith_write_r_r_offs_ptr_c(cond, r, rs, offs) \
  841. emith_write_r_r_offs_ptr(r, rs, offs)
  842. #define emith_write_r_r_r_ptr(r, rs, rm) do { \
  843. emith_add_r_r_r(AT, rs, rm); \
  844. EMIT(MIPS_SW(r, AT, 0)); \
  845. } while (0)
  846. #define emith_write_r_r_r_ptr_c(cond, r, rs, rm) \
  847. emith_write_r_r_r_ptr(r, rs, rm)
  848. #define emith_write_r_r_offs(r, rs, offs) \
  849. emith_write_r_r_offs_ptr(r, rs, offs)
  850. #define emith_write_r_r_offs_c(cond, r, rs, offs) \
  851. emith_write_r_r_offs(r, rs, offs)
  852. #define emith_write_r_r_r(r, rs, rm) \
  853. emith_write_r_r_r_ptr(r, rs, rm)
  854. #define emith_write_r_r_r_c(cond, r, rs, rm) \
  855. emith_write_r_r_r(r, rs, rm)
  856. #define emith_write_r_r_r_ptr_wb(r, rs, rm) do { \
  857. emith_add_r_r_r(rs, rs, rm); \
  858. EMIT(MIPS_SW(r, rs, 0)); \
  859. } while (0)
  860. #define emith_write_r_r_r_wb(r, rs, rm) \
  861. emith_write_r_r_r_ptr_wb(r, rs, rm)
  862. #define emith_ctx_read_ptr(r, offs) \
  863. emith_read_r_r_offs_ptr(r, CONTEXT_REG, offs)
  864. #define emith_ctx_read(r, offs) \
  865. emith_read_r_r_offs(r, CONTEXT_REG, offs)
  866. #define emith_ctx_read_c(cond, r, offs) \
  867. emith_ctx_read(r, offs)
  868. #define emith_ctx_write_ptr(r, offs) \
  869. emith_write_r_r_offs_ptr(r, CONTEXT_REG, offs)
  870. #define emith_ctx_write(r, offs) \
  871. emith_write_r_r_offs(r, CONTEXT_REG, offs)
  872. #define emith_ctx_read_multiple(r, offs, cnt, tmpr) do { \
  873. int r_ = r, offs_ = offs, cnt_ = cnt; \
  874. for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
  875. emith_ctx_read(r_, offs_); \
  876. } while (0)
  877. #define emith_ctx_write_multiple(r, offs, cnt, tmpr) do { \
  878. int r_ = r, offs_ = offs, cnt_ = cnt; \
  879. for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
  880. emith_ctx_write(r_, offs_); \
  881. } while (0)
  882. // function call handling
  883. #define emith_save_caller_regs(mask) do { \
  884. int _c; u32 _m = mask & 0x300fffc; /* r2-r15,r24-r25 */ \
  885. if (__builtin_parity(_m) == 1) _m |= 0x1; /* ABI align */ \
  886. int _s = count_bits(_m) * 4, _o = _s; \
  887. if (_s) emith_sub_r_imm(SP, _s); \
  888. for (_c = HOST_REGS; _m && _c >= 0; _m &= ~(1 << _c), _c--) \
  889. if (_m & (1 << _c)) \
  890. { _o -= 4; if (_c) emith_write_r_r_offs(_c, SP, _o); } \
  891. } while (0)
  892. #define emith_restore_caller_regs(mask) do { \
  893. int _c; u32 _m = mask & 0x300fffc; \
  894. if (__builtin_parity(_m) == 1) _m |= 0x1; \
  895. int _s = count_bits(_m) * 4, _o = 0; \
  896. for (_c = 0; _m && _c < HOST_REGS; _m &= ~(1 << _c), _c++) \
  897. if (_m & (1 << _c)) \
  898. { if (_c) emith_read_r_r_offs(_c, SP, _o); _o += 4; } \
  899. if (_s) emith_add_r_imm(SP, _s); \
  900. } while (0)
  901. #define host_arg2reg(rd, arg) \
  902. rd = (arg+4)
  903. #define emith_pass_arg_r(arg, reg) \
  904. emith_move_r_r(arg, reg)
  905. #define emith_pass_arg_imm(arg, imm) \
  906. emith_move_r_imm(arg, imm)
  907. // branching
  908. #define emith_invert_branch(cond) /* inverted conditional branch */ \
  909. (((cond) >> 5) == OP__RT ? (cond) ^ 0x01 : (cond) ^ 0x20)
  910. // evaluate the emulated condition, returns a register/branch type pair
  911. static int emith_cond_check(int cond, int *r)
  912. {
  913. int b = 0;
  914. // shortcut for comparing 2 registers
  915. if (emith_flg_rs || emith_flg_rt) switch (cond) {
  916. case DCOND_LS: EMIT(MIPS_SLTU_REG(AT, emith_flg_rs, emith_flg_rt));
  917. *r = AT, b = MIPS_BEQ; break; // s <= t unsigned
  918. case DCOND_HI: EMIT(MIPS_SLTU_REG(AT, emith_flg_rs, emith_flg_rt));
  919. *r = AT, b = MIPS_BNE; break; // s > t unsigned
  920. case DCOND_LT: EMIT(MIPS_SLT_REG(AT, emith_flg_rt, emith_flg_rs));
  921. *r = AT, b = MIPS_BNE; break; // s < t
  922. case DCOND_GE: EMIT(MIPS_SLT_REG(AT, emith_flg_rt, emith_flg_rs));
  923. *r = AT, b = MIPS_BEQ; break; // s >= t
  924. case DCOND_LE: EMIT(MIPS_SLT_REG(AT, emith_flg_rs, emith_flg_rt));
  925. *r = AT, b = MIPS_BEQ; break; // s <= t
  926. case DCOND_GT: EMIT(MIPS_SLT_REG(AT, emith_flg_rs, emith_flg_rt));
  927. *r = AT, b = MIPS_BNE; break; // s > t
  928. }
  929. // shortcut for V known to be 0
  930. if (!b && emith_flg_noV) switch (cond) {
  931. case DCOND_VS: *r = Z0; b = MIPS_BNE; break; // never
  932. case DCOND_VC: *r = Z0; b = MIPS_BEQ; break; // always
  933. case DCOND_LT: *r = FNZ, b = MIPS_BLT; break; // N
  934. case DCOND_GE: *r = FNZ, b = MIPS_BGE; break; // !N
  935. case DCOND_LE: *r = FNZ, b = MIPS_BLE; break; // N || Z
  936. case DCOND_GT: *r = FNZ, b = MIPS_BGT; break; // !N && !Z
  937. }
  938. // the full monty if no shortcut
  939. if (!b) switch (cond) {
  940. // conditions using NZ
  941. case DCOND_EQ: *r = FNZ; b = MIPS_BEQ; break; // Z
  942. case DCOND_NE: *r = FNZ; b = MIPS_BNE; break; // !Z
  943. case DCOND_MI: *r = FNZ; b = MIPS_BLT; break; // N
  944. case DCOND_PL: *r = FNZ; b = MIPS_BGE; break; // !N
  945. // conditions using C
  946. case DCOND_LO: *r = FC; b = MIPS_BNE; break; // C
  947. case DCOND_HS: *r = FC; b = MIPS_BEQ; break; // !C
  948. // conditions using CZ
  949. case DCOND_LS: // C || Z
  950. case DCOND_HI: // !C && !Z
  951. EMIT(MIPS_ADD_IMM(AT, FC, (u16)-1)); // !C && !Z
  952. EMIT(MIPS_AND_REG(AT, FNZ, AT));
  953. *r = AT, b = (cond == DCOND_HI ? MIPS_BNE : MIPS_BEQ);
  954. break;
  955. // conditions using V
  956. case DCOND_VS: // V
  957. case DCOND_VC: // !V
  958. EMIT(MIPS_XOR_REG(AT, FV, FNZ)); // V = Nt^Ns^Nd^C
  959. EMIT(MIPS_LSR_IMM(AT, AT, 31));
  960. EMIT(MIPS_XOR_REG(AT, AT, FC));
  961. *r = AT, b = (cond == DCOND_VS ? MIPS_BNE : MIPS_BEQ);
  962. break;
  963. // conditions using VNZ
  964. case DCOND_LT: // N^V
  965. case DCOND_GE: // !(N^V)
  966. EMIT(MIPS_LSR_IMM(AT, FV, 31)); // Nd^V = Nt^Ns^C
  967. EMIT(MIPS_XOR_REG(AT, FC, AT));
  968. *r = AT, b = (cond == DCOND_LT ? MIPS_BNE : MIPS_BEQ);
  969. break;
  970. case DCOND_LE: // (N^V) || Z
  971. case DCOND_GT: // !(N^V) && !Z
  972. EMIT(MIPS_LSR_IMM(AT, FV, 31)); // Nd^V = Nt^Ns^C
  973. EMIT(MIPS_XOR_REG(AT, FC, AT));
  974. EMIT(MIPS_ADD_IMM(AT, AT, (u16)-1)); // !(Nd^V) && !Z
  975. EMIT(MIPS_AND_REG(AT, FNZ, AT));
  976. *r = AT, b = (cond == DCOND_GT ? MIPS_BNE : MIPS_BEQ);
  977. break;
  978. }
  979. return b;
  980. }
  981. // NB: assumes all targets are in the same 256MB segment
  982. #define emith_jump(target) \
  983. emith_branch(MIPS_J((uintptr_t)target & 0x0fffffff))
  984. #define emith_jump_patchable(target) \
  985. emith_jump(target)
  986. // NB: MIPS conditional branches have only +/- 128KB range
  987. #define emith_jump_cond(cond, target) do { \
  988. int r_, mcond_ = emith_cond_check(cond, &r_); \
  989. u32 disp_ = (u8 *)target - emith_insn_ptr() - 4; \
  990. if (disp_ >= 0xfffe0000 || disp_ <= 0x0001ffff) { /* can use near B */ \
  991. emith_branch(MIPS_BCONDZ(mcond_,r_,disp_ & 0x0003ffff)); \
  992. } else { /* far branch if near branch isn't possible */ \
  993. mcond_ = emith_invert_branch(mcond_); \
  994. u8 *bp = emith_branch(MIPS_BCONDZ(mcond_, r_, 0)); \
  995. emith_branch(MIPS_J((uintptr_t)target & 0x0fffffff)); \
  996. EMIT_PTR(bp, MIPS_BCONDZ(mcond_, r_, emith_insn_ptr()-bp-4)); \
  997. } \
  998. } while (0)
  999. #define emith_jump_cond_patchable(cond, target) do { \
  1000. int r_, mcond_ = emith_cond_check(cond, &r_); \
  1001. mcond_ = emith_invert_branch(mcond_); \
  1002. u8 *bp = emith_branch(MIPS_BCONDZ(mcond_, r_, 0));\
  1003. emith_branch(MIPS_J((uintptr_t)target & 0x0fffffff)); \
  1004. EMIT_PTR(bp, MIPS_BCONDZ(mcond_, r_, emith_insn_ptr()-bp-4)); \
  1005. } while (0)
  1006. // NB: returns position of patch for cache maintenance
  1007. #define emith_jump_patch(ptr, target) ({ \
  1008. u32 *ptr_ = (u32 *)ptr-1; /* must skip condition check code */ \
  1009. while ((ptr_[0] & 0xf8000000) != OP_J << 26) ptr_ ++; \
  1010. EMIT_PTR(ptr_, MIPS_J((uintptr_t)target & 0x0fffffff)); \
  1011. (u8 *)(ptr_-1); \
  1012. })
  1013. #define emith_jump_reg(r) \
  1014. emith_branch(MIPS_JR(r))
  1015. #define emith_jump_reg_c(cond, r) \
  1016. emith_jump_reg(r)
  1017. #define emith_jump_ctx(offs) do { \
  1018. emith_ctx_read_ptr(AT, offs); \
  1019. emith_jump_reg(AT); \
  1020. } while (0)
  1021. #define emith_jump_ctx_c(cond, offs) \
  1022. emith_jump_ctx(offs)
  1023. #define emith_call(target) \
  1024. emith_branch(MIPS_JAL((uintptr_t)target & 0x0fffffff))
  1025. #define emith_call_cond(cond, target) \
  1026. emith_call(target)
  1027. #define emith_call_reg(r) \
  1028. emith_branch(MIPS_JALR(LR, r))
  1029. #define emith_call_ctx(offs) do { \
  1030. emith_ctx_read_ptr(AT, offs); \
  1031. emith_call_reg(AT); \
  1032. } while (0)
  1033. #define emith_call_link(r, target) do { \
  1034. EMIT(MIPS_BL(4)); EMIT(MIPS_ADD_IMM(r, LR, 8)); emith_flush(); \
  1035. emith_branch(MIPS_J((uintptr_t)target & 0x0fffffff)); \
  1036. } while (0)
  1037. #define emith_call_cleanup() /**/
  1038. #define emith_ret() \
  1039. emith_branch(MIPS_JR(LR))
  1040. #define emith_ret_c(cond) \
  1041. emith_ret()
  1042. #define emith_ret_to_ctx(offs) \
  1043. emith_ctx_write_ptr(LR, offs)
  1044. // NB: ABI SP alignment is 8 for compatibility with MIPS IV
  1045. #define emith_push_ret(r) do { \
  1046. emith_sub_r_imm(SP, 8+16); /* reserve new arg save area (16) */ \
  1047. emith_write_r_r_offs(LR, SP, 4+16); \
  1048. if ((r) >= 0) emith_write_r_r_offs(r, SP, 0+16); \
  1049. } while (0)
  1050. #define emith_pop_and_ret(r) do { \
  1051. if ((r) >= 0) emith_read_r_r_offs(r, SP, 0+16); \
  1052. emith_read_r_r_offs(LR, SP, 4+16); \
  1053. emith_add_r_imm(SP, 8+16); \
  1054. emith_ret(); \
  1055. } while (0)
  1056. // emitter ABI stuff
  1057. #define emith_pool_check() /**/
  1058. #define emith_pool_commit(j) /**/
  1059. // NB: mips32r2 has SYNCI
  1060. #define host_instructions_updated(base, end) __builtin___clear_cache(base, end)
  1061. #define emith_jump_patch_size() 4
  1062. #define emith_rw_offs_max() 0x7fff
  1063. // SH2 drc specific
  1064. #define emith_sh2_drc_entry() do { \
  1065. int _c; u32 _m = 0xd0ff0000; \
  1066. if (__builtin_parity(_m) == 1) _m |= 0x1; /* ABI align for SP is 8 */ \
  1067. int _s = count_bits(_m) * 4 + 16, _o = _s; /* 16 byte arg save area */ \
  1068. if (_s) emith_sub_r_imm(SP, _s); \
  1069. for (_c = HOST_REGS; _m && _c >= 0; _m &= ~(1 << _c), _c--) \
  1070. if (_m & (1 << _c)) \
  1071. { _o -= 4; if (_c) emith_write_r_r_offs(_c, SP, _o); } \
  1072. } while (0)
  1073. #define emith_sh2_drc_exit() do { \
  1074. int _c; u32 _m = 0xd0ff0000; \
  1075. if (__builtin_parity(_m) == 1) _m |= 0x1; \
  1076. int _s = count_bits(_m) * 4 + 16, _o = 16; \
  1077. for (_c = 0; _m && _c < HOST_REGS; _m &= ~(1 << _c), _c++) \
  1078. if (_m & (1 << _c)) \
  1079. { if (_c) emith_read_r_r_offs(_c, SP, _o); _o += 4; } \
  1080. if (_s) emith_add_r_imm(SP, _s); \
  1081. emith_ret(); \
  1082. } while (0)
  1083. // NB: assumes a is in arg0, tab, func and mask are temp
  1084. #define emith_sh2_rcall(a, tab, func, mask) do { \
  1085. emith_lsr(mask, a, SH2_READ_SHIFT); \
  1086. emith_add_r_r_r_lsl_ptr(tab, tab, mask, 3); \
  1087. emith_read_r_r_offs_ptr(func, tab, 0); \
  1088. emith_read_r_r_offs(mask, tab, 4); \
  1089. emith_addf_r_r_r/*_ptr*/(func, func, func); \
  1090. } while (0)
  1091. // NB: assumes a, val are in arg0 and arg1, tab and func are temp
  1092. #define emith_sh2_wcall(a, val, tab, func) do { \
  1093. emith_lsr(func, a, SH2_WRITE_SHIFT); \
  1094. emith_lsl(func, func, 2); \
  1095. emith_read_r_r_r_ptr(func, tab, func); \
  1096. emith_move_r_r_ptr(6, CONTEXT_REG); /* arg2 */ \
  1097. emith_jump_reg(func); \
  1098. } while (0)
  1099. #define emith_sh2_delay_loop(cycles, reg) do { \
  1100. int sr = rcache_get_reg(SHR_SR, RC_GR_RMW, NULL); \
  1101. int t1 = rcache_get_tmp(); \
  1102. int t2 = rcache_get_tmp(); \
  1103. int t3 = rcache_get_tmp(); \
  1104. /* if (sr < 0) return */ \
  1105. emith_cmp_r_imm(sr, 0); \
  1106. EMITH_JMP_START(DCOND_LE); \
  1107. /* turns = sr.cycles / cycles */ \
  1108. emith_asr(t2, sr, 12); \
  1109. emith_move_r_imm(t3, (u32)((1ULL<<32) / (cycles)) + 1); \
  1110. emith_mul_u64(t1, t2, t2, t3); /* multiply by 1/x */ \
  1111. rcache_free_tmp(t3); \
  1112. if (reg >= 0) { \
  1113. /* if (reg <= turns) turns = reg-1 */ \
  1114. t3 = rcache_get_reg(reg, RC_GR_RMW, NULL); \
  1115. emith_cmp_r_r(t3, t2); \
  1116. EMITH_SJMP_START(DCOND_HI); \
  1117. emith_sub_r_r_imm_c(DCOND_LS, t2, t3, 1); \
  1118. EMITH_SJMP_END(DCOND_HI); \
  1119. /* if (reg <= 1) turns = 0 */ \
  1120. emith_cmp_r_imm(t3, 1); \
  1121. EMITH_SJMP_START(DCOND_HI); \
  1122. emith_move_r_imm_c(DCOND_LS, t2, 0); \
  1123. EMITH_SJMP_END(DCOND_HI); \
  1124. /* reg -= turns */ \
  1125. emith_sub_r_r(t3, t2); \
  1126. } \
  1127. /* sr.cycles -= turns * cycles; */ \
  1128. emith_move_r_imm(t1, cycles); \
  1129. emith_mul(t1, t2, t1); \
  1130. emith_sub_r_r_r_lsl(sr, sr, t1, 12); \
  1131. EMITH_JMP_END(DCOND_LE); \
  1132. rcache_free_tmp(t1); \
  1133. rcache_free_tmp(t2); \
  1134. } while (0)
  1135. /*
  1136. * if Q
  1137. * t = carry(Rn += Rm)
  1138. * else
  1139. * t = carry(Rn -= Rm)
  1140. * T ^= t
  1141. */
  1142. #define emith_sh2_div1_step(rn, rm, sr) do { \
  1143. emith_tst_r_imm(sr, Q); /* if (Q ^ M) */ \
  1144. EMITH_JMP3_START(DCOND_EQ); \
  1145. emith_addf_r_r(rn, rm); \
  1146. EMITH_JMP3_MID(DCOND_EQ); \
  1147. emith_subf_r_r(rn, rm); \
  1148. EMITH_JMP3_END(); \
  1149. emith_eor_r_r(sr, FC); \
  1150. } while (0)
  1151. /* mh:ml += rn*rm, does saturation if required by S bit. rn, rm must be TEMP */
  1152. #define emith_sh2_macl(ml, mh, rn, rm, sr) do { \
  1153. emith_tst_r_imm(sr, S); \
  1154. EMITH_SJMP_START(DCOND_EQ); \
  1155. /* MACH top 16 bits unused if saturated. sign ext for overfl detect */ \
  1156. emith_sext(mh, mh, 16); \
  1157. EMITH_SJMP_END(DCOND_EQ); \
  1158. emith_mula_s64(ml, mh, rn, rm); \
  1159. emith_tst_r_imm(sr, S); \
  1160. EMITH_SJMP_START(DCOND_EQ); \
  1161. /* overflow if top 17 bits of MACH aren't all 1 or 0 */ \
  1162. /* to check: add MACH[15] to MACH[31:16]. this is 0 if no overflow */ \
  1163. emith_asrf(rn, mh, 16); /* sum = (MACH>>16) + ((MACH>>15)&1) */ \
  1164. emith_adcf_r_imm(rn, 0); /* (MACH>>15) is in carry after shift */ \
  1165. EMITH_SJMP_START(DCOND_EQ); /* sum != 0 -> ov */ \
  1166. emith_move_r_imm_c(DCOND_NE, ml, 0x0000); /* -overflow */ \
  1167. emith_move_r_imm_c(DCOND_NE, mh, 0x8000); \
  1168. EMITH_SJMP_START(DCOND_LE); /* sum > 0 -> +ovl */ \
  1169. emith_sub_r_imm_c(DCOND_GT, ml, 1); /* 0xffffffff */ \
  1170. emith_sub_r_imm_c(DCOND_GT, mh, 1); /* 0x00007fff */ \
  1171. EMITH_SJMP_END(DCOND_LE); \
  1172. EMITH_SJMP_END(DCOND_EQ); \
  1173. EMITH_SJMP_END(DCOND_EQ); \
  1174. } while (0)
  1175. /* mh:ml += rn*rm, does saturation if required by S bit. rn, rm must be TEMP */
  1176. #define emith_sh2_macw(ml, mh, rn, rm, sr) do { \
  1177. emith_tst_r_imm(sr, S); \
  1178. EMITH_SJMP_START(DCOND_EQ); \
  1179. /* XXX: MACH should be untouched when S is set? */ \
  1180. emith_asr(mh, ml, 31); /* sign ext MACL to MACH for ovrfl check */ \
  1181. EMITH_SJMP_END(DCOND_EQ); \
  1182. emith_mula_s64(ml, mh, rn, rm); \
  1183. emith_tst_r_imm(sr, S); \
  1184. EMITH_SJMP_START(DCOND_EQ); \
  1185. /* overflow if top 33 bits of MACH:MACL aren't all 1 or 0 */ \
  1186. /* to check: add MACL[31] to MACH. this is 0 if no overflow */ \
  1187. emith_lsr(rn, ml, 31); \
  1188. emith_addf_r_r(rn, mh); /* sum = MACH + ((MACL>>31)&1) */ \
  1189. EMITH_SJMP_START(DCOND_EQ); /* sum != 0 -> overflow */ \
  1190. /* XXX: LSB signalling only in SH1, or in SH2 too? */ \
  1191. emith_move_r_imm_c(DCOND_NE, mh, 0x00000001); /* LSB of MACH */ \
  1192. emith_move_r_imm_c(DCOND_NE, ml, 0x80000000); /* negative ovrfl */ \
  1193. EMITH_SJMP_START(DCOND_LE); /* sum > 0 -> positive ovrfl */ \
  1194. emith_sub_r_imm_c(DCOND_GT, ml, 1); /* 0x7fffffff */ \
  1195. EMITH_SJMP_END(DCOND_LE); \
  1196. EMITH_SJMP_END(DCOND_EQ); \
  1197. EMITH_SJMP_END(DCOND_EQ); \
  1198. } while (0)
  1199. #define emith_write_sr(sr, srcr) do { \
  1200. emith_lsr(sr, sr, 10); \
  1201. emith_or_r_r_r_lsl(sr, sr, srcr, 22); \
  1202. emith_ror(sr, sr, 22); \
  1203. } while (0)
  1204. #define emith_carry_to_t(srr, is_sub) do { \
  1205. emith_lsr(sr, sr, 1); \
  1206. emith_adc_r_r(sr, sr); \
  1207. } while (0)
  1208. #define emith_tpop_carry(sr, is_sub) do { \
  1209. emith_and_r_r_imm(FC, sr, 1); \
  1210. emith_lsr(sr, sr, 1); \
  1211. } while (0)
  1212. #define emith_tpush_carry(sr, is_sub) \
  1213. emith_adc_r_r(sr, sr)
  1214. #ifdef T
  1215. // T bit handling
  1216. #define emith_invert_cond(cond) \
  1217. ((cond) ^ 1)
  1218. static void emith_clr_t_cond(int sr)
  1219. {
  1220. emith_bic_r_imm(sr, T);
  1221. }
  1222. static void emith_set_t_cond(int sr, int cond)
  1223. {
  1224. EMITH_SJMP_START(emith_invert_cond(cond));
  1225. emith_or_r_imm_c(cond, sr, T);
  1226. EMITH_SJMP_END(emith_invert_cond(cond));
  1227. }
  1228. #define emith_get_t_cond() -1
  1229. #define emith_sync_t(sr) ((void)sr)
  1230. #define emith_invalidate_t()
  1231. static void emith_set_t(int sr, int val)
  1232. {
  1233. if (val)
  1234. emith_or_r_imm(sr, T);
  1235. else
  1236. emith_bic_r_imm(sr, T);
  1237. }
  1238. static int emith_tst_t(int sr, int tf)
  1239. {
  1240. emith_tst_r_imm(sr, T);
  1241. return tf ? DCOND_NE: DCOND_EQ;
  1242. }
  1243. #endif