emit_mips.c 53 KB

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