compiler.c 116 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126
  1. /*
  2. * SH2 recompiler
  3. * (C) notaz, 2009,2010,2013
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. *
  8. * notes:
  9. * - tcache, block descriptor, link buffer overflows result in sh2_translate()
  10. * failure, followed by full tcache invalidation for that region
  11. * - jumps between blocks are tracked for SMC handling (in block_entry->links),
  12. * except jumps between different tcaches
  13. *
  14. * implemented:
  15. * - static register allocation
  16. * - remaining register caching and tracking in temporaries
  17. * - block-local branch linking
  18. * - block linking (except between tcaches)
  19. * - some constant propagation
  20. *
  21. * TODO:
  22. * - better constant propagation
  23. * - stack caching?
  24. * - bug fixing
  25. */
  26. #include <stddef.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <assert.h>
  30. #include "../../pico/pico_int.h"
  31. #include "sh2.h"
  32. #include "compiler.h"
  33. #include "../drc/cmn.h"
  34. #include "../debug.h"
  35. // features
  36. #define PROPAGATE_CONSTANTS 1
  37. #define LINK_BRANCHES 1
  38. // limits (per block)
  39. #define MAX_BLOCK_SIZE (BLOCK_INSN_LIMIT * 6 * 6)
  40. // max literal offset from the block end
  41. #define MAX_LITERAL_OFFSET 32*2
  42. #define MAX_LITERALS (BLOCK_INSN_LIMIT / 4)
  43. #define MAX_LOCAL_BRANCHES 32
  44. // debug stuff
  45. // 1 - warnings/errors
  46. // 2 - block info/smc
  47. // 4 - asm
  48. // 8 - runtime block entry log
  49. // {
  50. #ifndef DRC_DEBUG
  51. #define DRC_DEBUG 0
  52. #endif
  53. #if DRC_DEBUG
  54. #define dbg(l,...) { \
  55. if ((l) & DRC_DEBUG) \
  56. elprintf(EL_STATUS, ##__VA_ARGS__); \
  57. }
  58. #include "mame/sh2dasm.h"
  59. #include <platform/libpicofe/linux/host_dasm.h>
  60. static int insns_compiled, hash_collisions, host_insn_count;
  61. #define COUNT_OP \
  62. host_insn_count++
  63. #else // !DRC_DEBUG
  64. #define COUNT_OP
  65. #define dbg(...)
  66. #endif
  67. ///
  68. #define FETCH_OP(pc) \
  69. dr_pc_base[(pc) / 2]
  70. #define FETCH32(a) \
  71. ((dr_pc_base[(a) / 2] << 16) | dr_pc_base[(a) / 2 + 1])
  72. #define CHECK_UNHANDLED_BITS(mask, label) { \
  73. if ((op & (mask)) != 0) \
  74. goto label; \
  75. }
  76. #define GET_Fx() \
  77. ((op >> 4) & 0x0f)
  78. #define GET_Rm GET_Fx
  79. #define GET_Rn() \
  80. ((op >> 8) & 0x0f)
  81. #define BITMASK1(v0) (1 << (v0))
  82. #define BITMASK2(v0,v1) ((1 << (v0)) | (1 << (v1)))
  83. #define BITMASK3(v0,v1,v2) (BITMASK2(v0,v1) | (1 << (v2)))
  84. #define BITMASK4(v0,v1,v2,v3) (BITMASK3(v0,v1,v2) | (1 << (v3)))
  85. #define BITMASK5(v0,v1,v2,v3,v4) (BITMASK4(v0,v1,v2,v3) | (1 << (v4)))
  86. #define SHR_T SHR_SR // might make them separate someday
  87. static struct op_data {
  88. u8 op;
  89. u8 cycles;
  90. u8 size; // 0, 1, 2 - byte, word, long
  91. s8 rm; // branch or load/store data reg
  92. u32 source; // bitmask of src regs
  93. u32 dest; // bitmask of dest regs
  94. u32 imm; // immediate/io address/branch target
  95. // (for literal - address, not value)
  96. } ops[BLOCK_INSN_LIMIT];
  97. enum op_types {
  98. OP_UNHANDLED = 0,
  99. OP_BRANCH,
  100. OP_BRANCH_CT, // conditional, branch if T set
  101. OP_BRANCH_CF, // conditional, branch if T clear
  102. OP_BRANCH_R, // indirect
  103. OP_BRANCH_RF, // indirect far (PC + Rm)
  104. OP_SETCLRT, // T flag set/clear
  105. OP_MOVE, // register move
  106. OP_LOAD_POOL, // literal pool load, imm is address
  107. OP_MOVA,
  108. OP_SLEEP,
  109. OP_RTE,
  110. };
  111. #ifdef DRC_SH2
  112. static int literal_disabled_frames;
  113. #if (DRC_DEBUG & 4)
  114. static u8 *tcache_dsm_ptrs[3];
  115. static char sh2dasm_buff[64];
  116. #define do_host_disasm(tcid) \
  117. host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
  118. tcache_dsm_ptrs[tcid] = tcache_ptr
  119. #else
  120. #define do_host_disasm(x)
  121. #endif
  122. #if (DRC_DEBUG & 8) || defined(PDB)
  123. static void REGPARM(3) *sh2_drc_log_entry(void *block, SH2 *sh2, u32 sr)
  124. {
  125. if (block != NULL) {
  126. dbg(8, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
  127. sh2->pc, block, (signed int)sr >> 12);
  128. pdb_step(sh2, sh2->pc);
  129. }
  130. return block;
  131. }
  132. #endif
  133. // } debug
  134. #define TCACHE_BUFFERS 3
  135. // we have 3 translation cache buffers, split from one drc/cmn buffer.
  136. // BIOS shares tcache with data array because it's only used for init
  137. // and can be discarded early
  138. // XXX: need to tune sizes
  139. static const int tcache_sizes[TCACHE_BUFFERS] = {
  140. DRC_TCACHE_SIZE * 6 / 8, // ROM (rarely used), DRAM
  141. DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
  142. DRC_TCACHE_SIZE / 8, // ... slave
  143. };
  144. static u8 *tcache_bases[TCACHE_BUFFERS];
  145. static u8 *tcache_ptrs[TCACHE_BUFFERS];
  146. // ptr for code emiters
  147. static u8 *tcache_ptr;
  148. #define MAX_BLOCK_ENTRIES (BLOCK_INSN_LIMIT / 8)
  149. struct block_link {
  150. u32 target_pc;
  151. void *jump; // insn address
  152. struct block_link *next; // either in block_entry->links or
  153. };
  154. struct block_entry {
  155. u32 pc;
  156. void *tcache_ptr; // translated block for above PC
  157. struct block_entry *next; // next block in hash_table with same pc hash
  158. struct block_link *links; // links to this entry
  159. #if (DRC_DEBUG & 2)
  160. struct block_desc *block;
  161. #endif
  162. };
  163. struct block_desc {
  164. u32 addr; // block start SH2 PC address
  165. u16 size; // ..of recompiled insns+lit. pool
  166. u16 size_nolit; // same without literals
  167. #if (DRC_DEBUG & 2)
  168. int refcount;
  169. #endif
  170. int entry_count;
  171. struct block_entry entryp[MAX_BLOCK_ENTRIES];
  172. };
  173. static const int block_max_counts[TCACHE_BUFFERS] = {
  174. 4*1024,
  175. 256,
  176. 256,
  177. };
  178. static struct block_desc *block_tables[TCACHE_BUFFERS];
  179. static int block_counts[TCACHE_BUFFERS];
  180. // we have block_link_pool to avoid using mallocs
  181. static const int block_link_pool_max_counts[TCACHE_BUFFERS] = {
  182. 4*1024,
  183. 256,
  184. 256,
  185. };
  186. static struct block_link *block_link_pool[TCACHE_BUFFERS];
  187. static int block_link_pool_counts[TCACHE_BUFFERS];
  188. static struct block_link *unresolved_links[TCACHE_BUFFERS];
  189. // used for invalidation
  190. static const int ram_sizes[TCACHE_BUFFERS] = {
  191. 0x40000,
  192. 0x1000,
  193. 0x1000,
  194. };
  195. #define INVAL_PAGE_SIZE 0x100
  196. struct block_list {
  197. struct block_desc *block;
  198. struct block_list *next;
  199. };
  200. // array of pointers to block_lists for RAM and 2 data arrays
  201. // each array has len: sizeof(mem) / INVAL_PAGE_SIZE
  202. static struct block_list **inval_lookup[TCACHE_BUFFERS];
  203. static const int hash_table_sizes[TCACHE_BUFFERS] = {
  204. 0x1000,
  205. 0x100,
  206. 0x100,
  207. };
  208. static struct block_entry **hash_tables[TCACHE_BUFFERS];
  209. #define HASH_FUNC(hash_tab, addr, mask) \
  210. (hash_tab)[(((addr) >> 20) ^ ((addr) >> 2)) & (mask)]
  211. // host register tracking
  212. enum {
  213. HR_FREE,
  214. HR_CACHED, // 'val' has sh2_reg_e
  215. // HR_CONST, // 'val' has a constant
  216. HR_TEMP, // reg used for temp storage
  217. };
  218. enum {
  219. HRF_DIRTY = 1 << 0, // reg has "dirty" value to be written to ctx
  220. HRF_LOCKED = 1 << 1, // HR_CACHED can't be evicted
  221. };
  222. typedef struct {
  223. u32 hreg:5; // "host" reg
  224. u32 greg:5; // "guest" reg
  225. u32 type:3;
  226. u32 flags:3;
  227. u32 stamp:16; // kind of a timestamp
  228. } temp_reg_t;
  229. // note: reg_temp[] must have at least the amount of
  230. // registers used by handlers in worst case (currently 4)
  231. #ifdef __arm__
  232. #include "../drc/emit_arm.c"
  233. #ifndef __MACH__
  234. static const int reg_map_g2h[] = {
  235. 4, 5, 6, 7,
  236. 8, -1, -1, -1,
  237. -1, -1, -1, -1,
  238. -1, -1, -1, 9, // r12 .. sp
  239. -1, -1, -1, 10, // SHR_PC, SHR_PPC, SHR_PR, SHR_SR,
  240. -1, -1, -1, -1, // SHR_GBR, SHR_VBR, SHR_MACH, SHR_MACL,
  241. };
  242. #else
  243. // no r9..
  244. static const int reg_map_g2h[] = {
  245. 4, 5, 6, 7,
  246. -1, -1, -1, -1,
  247. -1, -1, -1, -1,
  248. -1, -1, -1, 8, // r12 .. sp
  249. -1, -1, -1, 10, // SHR_PC, SHR_PPC, SHR_PR, SHR_SR,
  250. -1, -1, -1, -1, // SHR_GBR, SHR_VBR, SHR_MACH, SHR_MACL,
  251. };
  252. #endif
  253. static temp_reg_t reg_temp[] = {
  254. { 0, },
  255. { 1, },
  256. { 12, },
  257. { 14, },
  258. { 2, },
  259. { 3, },
  260. };
  261. #elif defined(__i386__)
  262. #include "../drc/emit_x86.c"
  263. static const int reg_map_g2h[] = {
  264. xSI,-1, -1, -1,
  265. -1, -1, -1, -1,
  266. -1, -1, -1, -1,
  267. -1, -1, -1, -1,
  268. -1, -1, -1, xDI,
  269. -1, -1, -1, -1,
  270. };
  271. // ax, cx, dx are usually temporaries by convention
  272. static temp_reg_t reg_temp[] = {
  273. { xAX, },
  274. { xBX, },
  275. { xCX, },
  276. { xDX, },
  277. };
  278. #else
  279. #error unsupported arch
  280. #endif
  281. #define T 0x00000001
  282. #define S 0x00000002
  283. #define I 0x000000f0
  284. #define Q 0x00000100
  285. #define M 0x00000200
  286. #define T_save 0x00000800
  287. #define I_SHIFT 4
  288. #define Q_SHIFT 8
  289. #define M_SHIFT 9
  290. static void REGPARM(1) (*sh2_drc_entry)(SH2 *sh2);
  291. static void (*sh2_drc_dispatcher)(void);
  292. static void (*sh2_drc_exit)(void);
  293. static void (*sh2_drc_test_irq)(void);
  294. static u32 REGPARM(2) (*sh2_drc_read8)(u32 a, SH2 *sh2);
  295. static u32 REGPARM(2) (*sh2_drc_read16)(u32 a, SH2 *sh2);
  296. static u32 REGPARM(2) (*sh2_drc_read32)(u32 a, SH2 *sh2);
  297. static void REGPARM(2) (*sh2_drc_write8)(u32 a, u32 d);
  298. static void REGPARM(2) (*sh2_drc_write16)(u32 a, u32 d);
  299. static void REGPARM(3) (*sh2_drc_write32)(u32 a, u32 d, SH2 *sh2);
  300. // address space stuff
  301. static int dr_ctx_get_mem_ptr(u32 a, u32 *mask)
  302. {
  303. int poffs = -1;
  304. if ((a & ~0x7ff) == 0) {
  305. // BIOS
  306. poffs = offsetof(SH2, p_bios);
  307. *mask = 0x7ff;
  308. }
  309. else if ((a & 0xfffff000) == 0xc0000000) {
  310. // data array
  311. // FIXME: access sh2->data_array instead
  312. poffs = offsetof(SH2, p_da);
  313. *mask = 0xfff;
  314. }
  315. else if ((a & 0xc6000000) == 0x06000000) {
  316. // SDRAM
  317. poffs = offsetof(SH2, p_sdram);
  318. *mask = 0x03ffff;
  319. }
  320. else if ((a & 0xc6000000) == 0x02000000) {
  321. // ROM
  322. poffs = offsetof(SH2, p_rom);
  323. *mask = 0x3fffff;
  324. }
  325. return poffs;
  326. }
  327. static struct block_entry *dr_get_entry(u32 pc, int is_slave, int *tcache_id)
  328. {
  329. struct block_entry *be;
  330. u32 tcid = 0, mask;
  331. // data arrays have their own caches
  332. if ((pc & 0xe0000000) == 0xc0000000 || (pc & ~0xfff) == 0)
  333. tcid = 1 + is_slave;
  334. *tcache_id = tcid;
  335. mask = hash_table_sizes[tcid] - 1;
  336. be = HASH_FUNC(hash_tables[tcid], pc, mask);
  337. for (; be != NULL; be = be->next)
  338. if (be->pc == pc)
  339. return be;
  340. return NULL;
  341. }
  342. // ---------------------------------------------------------------
  343. // block management
  344. static void add_to_block_list(struct block_list **blist, struct block_desc *block)
  345. {
  346. struct block_list *added = malloc(sizeof(*added));
  347. if (!added) {
  348. elprintf(EL_ANOMALY, "drc OOM (1)");
  349. return;
  350. }
  351. added->block = block;
  352. added->next = *blist;
  353. *blist = added;
  354. }
  355. static void rm_from_block_list(struct block_list **blist, struct block_desc *block)
  356. {
  357. struct block_list *prev = NULL, *current = *blist;
  358. for (; current != NULL; prev = current, current = current->next) {
  359. if (current->block == block) {
  360. if (prev == NULL)
  361. *blist = current->next;
  362. else
  363. prev->next = current->next;
  364. free(current);
  365. return;
  366. }
  367. }
  368. dbg(1, "can't rm block %p (%08x-%08x)",
  369. block, block->addr, block->addr + block->size);
  370. }
  371. static void rm_block_list(struct block_list **blist)
  372. {
  373. struct block_list *tmp, *current = *blist;
  374. while (current != NULL) {
  375. tmp = current;
  376. current = current->next;
  377. free(tmp);
  378. }
  379. *blist = NULL;
  380. }
  381. static void REGPARM(1) flush_tcache(int tcid)
  382. {
  383. int i;
  384. dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
  385. tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
  386. block_counts[tcid], block_max_counts[tcid]);
  387. block_counts[tcid] = 0;
  388. block_link_pool_counts[tcid] = 0;
  389. unresolved_links[tcid] = NULL;
  390. memset(hash_tables[tcid], 0, sizeof(*hash_tables[0]) * hash_table_sizes[tcid]);
  391. tcache_ptrs[tcid] = tcache_bases[tcid];
  392. if (Pico32xMem != NULL) {
  393. if (tcid == 0) // ROM, RAM
  394. memset(Pico32xMem->drcblk_ram, 0,
  395. sizeof(Pico32xMem->drcblk_ram));
  396. else
  397. memset(Pico32xMem->drcblk_da[tcid - 1], 0,
  398. sizeof(Pico32xMem->drcblk_da[0]));
  399. }
  400. #if (DRC_DEBUG & 4)
  401. tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
  402. #endif
  403. for (i = 0; i < ram_sizes[tcid] / INVAL_PAGE_SIZE; i++)
  404. rm_block_list(&inval_lookup[tcid][i]);
  405. }
  406. static void add_to_hashlist(struct block_entry *be, int tcache_id)
  407. {
  408. u32 tcmask = hash_table_sizes[tcache_id] - 1;
  409. be->next = HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask);
  410. HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask) = be;
  411. #if (DRC_DEBUG & 2)
  412. if (be->next != NULL) {
  413. printf(" %08x: hash collision with %08x\n",
  414. be->pc, be->next->pc);
  415. hash_collisions++;
  416. }
  417. #endif
  418. }
  419. static void rm_from_hashlist(struct block_entry *be, int tcache_id)
  420. {
  421. u32 tcmask = hash_table_sizes[tcache_id] - 1;
  422. struct block_entry *cur, *prev;
  423. cur = HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask);
  424. if (cur == NULL)
  425. goto missing;
  426. if (be == cur) { // first
  427. HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask) = be->next;
  428. return;
  429. }
  430. for (prev = cur, cur = cur->next; cur != NULL; cur = cur->next) {
  431. if (cur == be) {
  432. prev->next = cur->next;
  433. return;
  434. }
  435. }
  436. missing:
  437. dbg(1, "rm_from_hashlist: be %p %08x missing?", be, be->pc);
  438. }
  439. static struct block_desc *dr_add_block(u32 addr, u16 size_lit,
  440. u16 size_nolit, int is_slave, int *blk_id)
  441. {
  442. struct block_entry *be;
  443. struct block_desc *bd;
  444. int tcache_id;
  445. int *bcount;
  446. // do a lookup to get tcache_id and override check
  447. be = dr_get_entry(addr, is_slave, &tcache_id);
  448. if (be != NULL)
  449. dbg(1, "block override for %08x", addr);
  450. bcount = &block_counts[tcache_id];
  451. if (*bcount >= block_max_counts[tcache_id]) {
  452. dbg(1, "bd overflow for tcache %d", tcache_id);
  453. return NULL;
  454. }
  455. bd = &block_tables[tcache_id][*bcount];
  456. bd->addr = addr;
  457. bd->size = size_lit;
  458. bd->size_nolit = size_nolit;
  459. bd->entry_count = 1;
  460. bd->entryp[0].pc = addr;
  461. bd->entryp[0].tcache_ptr = tcache_ptr;
  462. bd->entryp[0].links = NULL;
  463. #if (DRC_DEBUG & 2)
  464. bd->entryp[0].block = bd;
  465. bd->refcount = 0;
  466. #endif
  467. add_to_hashlist(&bd->entryp[0], tcache_id);
  468. *blk_id = *bcount;
  469. (*bcount)++;
  470. return bd;
  471. }
  472. static void REGPARM(3) *dr_lookup_block(u32 pc, int is_slave, int *tcache_id)
  473. {
  474. struct block_entry *be = NULL;
  475. void *block = NULL;
  476. be = dr_get_entry(pc, is_slave, tcache_id);
  477. if (be != NULL)
  478. block = be->tcache_ptr;
  479. #if (DRC_DEBUG & 2)
  480. if (be != NULL)
  481. be->block->refcount++;
  482. #endif
  483. return block;
  484. }
  485. static void *dr_failure(void)
  486. {
  487. lprintf("recompilation failed\n");
  488. exit(1);
  489. }
  490. static void *dr_prepare_ext_branch(u32 pc, int is_slave, int tcache_id)
  491. {
  492. #if LINK_BRANCHES
  493. struct block_link *bl = block_link_pool[tcache_id];
  494. int cnt = block_link_pool_counts[tcache_id];
  495. struct block_entry *be = NULL;
  496. int target_tcache_id;
  497. int i;
  498. be = dr_get_entry(pc, is_slave, &target_tcache_id);
  499. if (target_tcache_id != tcache_id)
  500. return sh2_drc_dispatcher;
  501. // if pool has been freed, reuse
  502. for (i = cnt - 1; i >= 0; i--)
  503. if (bl[i].target_pc != 0)
  504. break;
  505. cnt = i + 1;
  506. if (cnt >= block_link_pool_max_counts[tcache_id]) {
  507. dbg(1, "bl overflow for tcache %d", tcache_id);
  508. return NULL;
  509. }
  510. bl += cnt;
  511. block_link_pool_counts[tcache_id]++;
  512. bl->target_pc = pc;
  513. bl->jump = tcache_ptr;
  514. if (be != NULL) {
  515. dbg(2, "- early link from %p to pc %08x", bl->jump, pc);
  516. bl->next = be->links;
  517. be->links = bl;
  518. return be->tcache_ptr;
  519. }
  520. else {
  521. bl->next = unresolved_links[tcache_id];
  522. unresolved_links[tcache_id] = bl;
  523. return sh2_drc_dispatcher;
  524. }
  525. #else
  526. return sh2_drc_dispatcher;
  527. #endif
  528. }
  529. static void dr_link_blocks(struct block_entry *be, int tcache_id)
  530. {
  531. #if LINK_BRANCHES
  532. struct block_link *first = unresolved_links[tcache_id];
  533. struct block_link *bl, *prev, *tmp;
  534. u32 pc = be->pc;
  535. for (bl = prev = first; bl != NULL; ) {
  536. if (bl->target_pc == pc) {
  537. dbg(2, "- link from %p to pc %08x", bl->jump, pc);
  538. emith_jump_patch(bl->jump, tcache_ptr);
  539. // move bl from unresolved_links to block_entry
  540. tmp = bl->next;
  541. bl->next = be->links;
  542. be->links = bl;
  543. if (bl == first)
  544. first = prev = bl = tmp;
  545. else
  546. prev->next = bl = tmp;
  547. continue;
  548. }
  549. prev = bl;
  550. bl = bl->next;
  551. }
  552. unresolved_links[tcache_id] = first;
  553. // could sync arm caches here, but that's unnecessary
  554. #endif
  555. }
  556. #define ADD_TO_ARRAY(array, count, item, failcode) \
  557. if (count >= ARRAY_SIZE(array)) { \
  558. dbg(1, "warning: " #array " overflow"); \
  559. failcode; \
  560. } \
  561. array[count++] = item;
  562. static int find_in_array(u32 *array, size_t size, u32 what)
  563. {
  564. size_t i;
  565. for (i = 0; i < size; i++)
  566. if (what == array[i])
  567. return i;
  568. return -1;
  569. }
  570. // ---------------------------------------------------------------
  571. // register cache / constant propagation stuff
  572. typedef enum {
  573. RC_GR_READ,
  574. RC_GR_WRITE,
  575. RC_GR_RMW,
  576. } rc_gr_mode;
  577. static int rcache_get_reg_(sh2_reg_e r, rc_gr_mode mode, int do_locking);
  578. // guest regs with constants
  579. static u32 dr_gcregs[24];
  580. // a mask of constant/dirty regs
  581. static u32 dr_gcregs_mask;
  582. static u32 dr_gcregs_dirty;
  583. #if PROPAGATE_CONSTANTS
  584. static void gconst_new(sh2_reg_e r, u32 val)
  585. {
  586. int i;
  587. dr_gcregs_mask |= 1 << r;
  588. dr_gcregs_dirty |= 1 << r;
  589. dr_gcregs[r] = val;
  590. // throw away old r that we might have cached
  591. for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
  592. if ((reg_temp[i].type == HR_CACHED) &&
  593. reg_temp[i].greg == r) {
  594. reg_temp[i].type = HR_FREE;
  595. reg_temp[i].flags = 0;
  596. }
  597. }
  598. }
  599. #endif
  600. static int gconst_get(sh2_reg_e r, u32 *val)
  601. {
  602. if (dr_gcregs_mask & (1 << r)) {
  603. *val = dr_gcregs[r];
  604. return 1;
  605. }
  606. return 0;
  607. }
  608. static int gconst_check(sh2_reg_e r)
  609. {
  610. if ((dr_gcregs_mask | dr_gcregs_dirty) & (1 << r))
  611. return 1;
  612. return 0;
  613. }
  614. // update hr if dirty, else do nothing
  615. static int gconst_try_read(int hr, sh2_reg_e r)
  616. {
  617. if (dr_gcregs_dirty & (1 << r)) {
  618. emith_move_r_imm(hr, dr_gcregs[r]);
  619. dr_gcregs_dirty &= ~(1 << r);
  620. return 1;
  621. }
  622. return 0;
  623. }
  624. static void gconst_check_evict(sh2_reg_e r)
  625. {
  626. if (dr_gcregs_mask & (1 << r))
  627. // no longer cached in reg, make dirty again
  628. dr_gcregs_dirty |= 1 << r;
  629. }
  630. static void gconst_kill(sh2_reg_e r)
  631. {
  632. dr_gcregs_mask &= ~(1 << r);
  633. dr_gcregs_dirty &= ~(1 << r);
  634. }
  635. static void gconst_clean(void)
  636. {
  637. int i;
  638. for (i = 0; i < ARRAY_SIZE(dr_gcregs); i++)
  639. if (dr_gcregs_dirty & (1 << i)) {
  640. // using RC_GR_READ here: it will call gconst_try_read,
  641. // cache the reg and mark it dirty.
  642. rcache_get_reg_(i, RC_GR_READ, 0);
  643. }
  644. }
  645. static void gconst_invalidate(void)
  646. {
  647. dr_gcregs_mask = dr_gcregs_dirty = 0;
  648. }
  649. static u16 rcache_counter;
  650. static temp_reg_t *rcache_evict(void)
  651. {
  652. // evict reg with oldest stamp
  653. int i, oldest = -1;
  654. u16 min_stamp = (u16)-1;
  655. for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
  656. if (reg_temp[i].type == HR_CACHED && !(reg_temp[i].flags & HRF_LOCKED) &&
  657. reg_temp[i].stamp <= min_stamp) {
  658. min_stamp = reg_temp[i].stamp;
  659. oldest = i;
  660. }
  661. }
  662. if (oldest == -1) {
  663. printf("no registers to evict, aborting\n");
  664. exit(1);
  665. }
  666. i = oldest;
  667. if (reg_temp[i].type == HR_CACHED) {
  668. if (reg_temp[i].flags & HRF_DIRTY)
  669. // writeback
  670. emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
  671. gconst_check_evict(reg_temp[i].greg);
  672. }
  673. reg_temp[i].type = HR_FREE;
  674. reg_temp[i].flags = 0;
  675. return &reg_temp[i];
  676. }
  677. static int get_reg_static(sh2_reg_e r, rc_gr_mode mode)
  678. {
  679. int i = reg_map_g2h[r];
  680. if (i != -1) {
  681. if (mode != RC_GR_WRITE)
  682. gconst_try_read(i, r);
  683. }
  684. return i;
  685. }
  686. // note: must not be called when doing conditional code
  687. static int rcache_get_reg_(sh2_reg_e r, rc_gr_mode mode, int do_locking)
  688. {
  689. temp_reg_t *tr;
  690. int i, ret;
  691. // maybe statically mapped?
  692. ret = get_reg_static(r, mode);
  693. if (ret != -1)
  694. goto end;
  695. rcache_counter++;
  696. // maybe already cached?
  697. // if so, prefer against gconst (they must be in sync)
  698. for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
  699. if (reg_temp[i].type == HR_CACHED && reg_temp[i].greg == r) {
  700. reg_temp[i].stamp = rcache_counter;
  701. if (mode != RC_GR_READ)
  702. reg_temp[i].flags |= HRF_DIRTY;
  703. ret = reg_temp[i].hreg;
  704. goto end;
  705. }
  706. }
  707. // use any free reg
  708. for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
  709. if (reg_temp[i].type == HR_FREE) {
  710. tr = &reg_temp[i];
  711. goto do_alloc;
  712. }
  713. }
  714. tr = rcache_evict();
  715. do_alloc:
  716. tr->type = HR_CACHED;
  717. if (do_locking)
  718. tr->flags |= HRF_LOCKED;
  719. if (mode != RC_GR_READ)
  720. tr->flags |= HRF_DIRTY;
  721. tr->greg = r;
  722. tr->stamp = rcache_counter;
  723. ret = tr->hreg;
  724. if (mode != RC_GR_WRITE) {
  725. if (gconst_check(r)) {
  726. if (gconst_try_read(ret, r))
  727. tr->flags |= HRF_DIRTY;
  728. }
  729. else
  730. emith_ctx_read(tr->hreg, r * 4);
  731. }
  732. end:
  733. if (mode != RC_GR_READ)
  734. gconst_kill(r);
  735. return ret;
  736. }
  737. static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
  738. {
  739. return rcache_get_reg_(r, mode, 1);
  740. }
  741. static int rcache_get_tmp(void)
  742. {
  743. temp_reg_t *tr;
  744. int i;
  745. for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
  746. if (reg_temp[i].type == HR_FREE) {
  747. tr = &reg_temp[i];
  748. goto do_alloc;
  749. }
  750. tr = rcache_evict();
  751. do_alloc:
  752. tr->type = HR_TEMP;
  753. return tr->hreg;
  754. }
  755. static int rcache_get_arg_id(int arg)
  756. {
  757. int i, r = 0;
  758. host_arg2reg(r, arg);
  759. for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
  760. if (reg_temp[i].hreg == r)
  761. break;
  762. if (i == ARRAY_SIZE(reg_temp)) // can't happen
  763. exit(1);
  764. if (reg_temp[i].type == HR_CACHED) {
  765. // writeback
  766. if (reg_temp[i].flags & HRF_DIRTY)
  767. emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
  768. gconst_check_evict(reg_temp[i].greg);
  769. }
  770. else if (reg_temp[i].type == HR_TEMP) {
  771. printf("arg %d reg %d already used, aborting\n", arg, r);
  772. exit(1);
  773. }
  774. reg_temp[i].type = HR_FREE;
  775. reg_temp[i].flags = 0;
  776. return i;
  777. }
  778. // get a reg to be used as function arg
  779. static int rcache_get_tmp_arg(int arg)
  780. {
  781. int id = rcache_get_arg_id(arg);
  782. reg_temp[id].type = HR_TEMP;
  783. return reg_temp[id].hreg;
  784. }
  785. // same but caches a reg. RC_GR_READ only.
  786. static int rcache_get_reg_arg(int arg, sh2_reg_e r)
  787. {
  788. int i, srcr, dstr, dstid;
  789. int dirty = 0, src_dirty = 0;
  790. dstid = rcache_get_arg_id(arg);
  791. dstr = reg_temp[dstid].hreg;
  792. // maybe already statically mapped?
  793. srcr = get_reg_static(r, RC_GR_READ);
  794. if (srcr != -1)
  795. goto do_cache;
  796. // maybe already cached?
  797. for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
  798. if ((reg_temp[i].type == HR_CACHED) &&
  799. reg_temp[i].greg == r)
  800. {
  801. srcr = reg_temp[i].hreg;
  802. if (reg_temp[i].flags & HRF_DIRTY)
  803. src_dirty = 1;
  804. goto do_cache;
  805. }
  806. }
  807. // must read
  808. srcr = dstr;
  809. if (gconst_check(r)) {
  810. if (gconst_try_read(srcr, r))
  811. dirty = 1;
  812. }
  813. else
  814. emith_ctx_read(srcr, r * 4);
  815. do_cache:
  816. if (dstr != srcr)
  817. emith_move_r_r(dstr, srcr);
  818. #if 1
  819. else
  820. dirty |= src_dirty;
  821. if (dirty)
  822. // must clean, callers might want to modify the arg before call
  823. emith_ctx_write(dstr, r * 4);
  824. #else
  825. if (dirty)
  826. reg_temp[dstid].flags |= HRF_DIRTY;
  827. #endif
  828. reg_temp[dstid].stamp = ++rcache_counter;
  829. reg_temp[dstid].type = HR_CACHED;
  830. reg_temp[dstid].greg = r;
  831. reg_temp[dstid].flags |= HRF_LOCKED;
  832. return dstr;
  833. }
  834. static void rcache_free_tmp(int hr)
  835. {
  836. int i;
  837. for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
  838. if (reg_temp[i].hreg == hr)
  839. break;
  840. if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
  841. printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
  842. return;
  843. }
  844. reg_temp[i].type = HR_FREE;
  845. reg_temp[i].flags = 0;
  846. }
  847. static void rcache_unlock(int hr)
  848. {
  849. int i;
  850. for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
  851. if (reg_temp[i].type == HR_CACHED && reg_temp[i].hreg == hr)
  852. reg_temp[i].flags &= ~HRF_LOCKED;
  853. }
  854. static void rcache_unlock_all(void)
  855. {
  856. int i;
  857. for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
  858. reg_temp[i].flags &= ~HRF_LOCKED;
  859. }
  860. static inline u32 rcache_used_hreg_mask(void)
  861. {
  862. u32 mask = 0;
  863. int i;
  864. for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
  865. if (reg_temp[i].type != HR_FREE)
  866. mask |= 1 << reg_temp[i].hreg;
  867. return mask;
  868. }
  869. static void rcache_clean(void)
  870. {
  871. int i;
  872. gconst_clean();
  873. for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
  874. if (reg_temp[i].type == HR_CACHED && (reg_temp[i].flags & HRF_DIRTY)) {
  875. // writeback
  876. emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
  877. reg_temp[i].flags &= ~HRF_DIRTY;
  878. }
  879. }
  880. static void rcache_invalidate(void)
  881. {
  882. int i;
  883. for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
  884. reg_temp[i].type = HR_FREE;
  885. reg_temp[i].flags = 0;
  886. }
  887. rcache_counter = 0;
  888. gconst_invalidate();
  889. }
  890. static void rcache_flush(void)
  891. {
  892. rcache_clean();
  893. rcache_invalidate();
  894. }
  895. // ---------------------------------------------------------------
  896. static int emit_get_rbase_and_offs(u32 a, u32 *offs)
  897. {
  898. u32 mask = 0;
  899. int poffs;
  900. int hr;
  901. poffs = dr_ctx_get_mem_ptr(a, &mask);
  902. if (poffs == -1)
  903. return -1;
  904. // XXX: could use some related reg
  905. hr = rcache_get_tmp();
  906. emith_ctx_read(hr, poffs);
  907. emith_add_r_imm(hr, a & mask & ~0xff);
  908. *offs = a & 0xff; // XXX: ARM oriented..
  909. return hr;
  910. }
  911. static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
  912. {
  913. #if PROPAGATE_CONSTANTS
  914. gconst_new(dst, imm);
  915. #else
  916. int hr = rcache_get_reg(dst, RC_GR_WRITE);
  917. emith_move_r_imm(hr, imm);
  918. #endif
  919. }
  920. static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
  921. {
  922. int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
  923. int hr_s = rcache_get_reg(src, RC_GR_READ);
  924. emith_move_r_r(hr_d, hr_s);
  925. }
  926. // T must be clear, and comparison done just before this
  927. static void emit_or_t_if_eq(int srr)
  928. {
  929. EMITH_SJMP_START(DCOND_NE);
  930. emith_or_r_imm_c(DCOND_EQ, srr, T);
  931. EMITH_SJMP_END(DCOND_NE);
  932. }
  933. // arguments must be ready
  934. // reg cache must be clean before call
  935. static int emit_memhandler_read_(int size, int ram_check)
  936. {
  937. int arg1;
  938. #if 0
  939. int arg0;
  940. host_arg2reg(arg0, 0);
  941. #endif
  942. rcache_clean();
  943. // must writeback cycles for poll detection stuff
  944. // FIXME: rm
  945. if (reg_map_g2h[SHR_SR] != -1)
  946. emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
  947. arg1 = rcache_get_tmp_arg(1);
  948. emith_move_r_r(arg1, CONTEXT_REG);
  949. #if 0 // can't do this because of unmapped reads
  950. // ndef PDB_NET
  951. if (ram_check && Pico.rom == (void *)0x02000000 && Pico32xMem->sdram == (void *)0x06000000) {
  952. int tmp = rcache_get_tmp();
  953. emith_and_r_r_imm(tmp, arg0, 0xfb000000);
  954. emith_cmp_r_imm(tmp, 0x02000000);
  955. switch (size) {
  956. case 0: // 8
  957. EMITH_SJMP3_START(DCOND_NE);
  958. emith_eor_r_imm_c(DCOND_EQ, arg0, 1);
  959. emith_read8_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
  960. EMITH_SJMP3_MID(DCOND_NE);
  961. emith_call_cond(DCOND_NE, sh2_drc_read8);
  962. EMITH_SJMP3_END();
  963. break;
  964. case 1: // 16
  965. EMITH_SJMP3_START(DCOND_NE);
  966. emith_read16_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
  967. EMITH_SJMP3_MID(DCOND_NE);
  968. emith_call_cond(DCOND_NE, sh2_drc_read16);
  969. EMITH_SJMP3_END();
  970. break;
  971. case 2: // 32
  972. EMITH_SJMP3_START(DCOND_NE);
  973. emith_read_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
  974. emith_ror_c(DCOND_EQ, arg0, arg0, 16);
  975. EMITH_SJMP3_MID(DCOND_NE);
  976. emith_call_cond(DCOND_NE, sh2_drc_read32);
  977. EMITH_SJMP3_END();
  978. break;
  979. }
  980. }
  981. else
  982. #endif
  983. {
  984. switch (size) {
  985. case 0: // 8
  986. emith_call(sh2_drc_read8);
  987. break;
  988. case 1: // 16
  989. emith_call(sh2_drc_read16);
  990. break;
  991. case 2: // 32
  992. emith_call(sh2_drc_read32);
  993. break;
  994. }
  995. }
  996. rcache_invalidate();
  997. if (reg_map_g2h[SHR_SR] != -1)
  998. emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
  999. // assuming arg0 and retval reg matches
  1000. return rcache_get_tmp_arg(0);
  1001. }
  1002. static int emit_memhandler_read(int size)
  1003. {
  1004. return emit_memhandler_read_(size, 1);
  1005. }
  1006. static int emit_memhandler_read_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int size)
  1007. {
  1008. int hr, hr2, ram_check = 1;
  1009. u32 val, offs2;
  1010. if (gconst_get(rs, &val)) {
  1011. hr = emit_get_rbase_and_offs(val + offs, &offs2);
  1012. if (hr != -1) {
  1013. hr2 = rcache_get_reg(rd, RC_GR_WRITE);
  1014. switch (size) {
  1015. case 0: // 8
  1016. emith_read8_r_r_offs(hr2, hr, offs2 ^ 1);
  1017. emith_sext(hr2, hr2, 8);
  1018. break;
  1019. case 1: // 16
  1020. emith_read16_r_r_offs(hr2, hr, offs2);
  1021. emith_sext(hr2, hr2, 16);
  1022. break;
  1023. case 2: // 32
  1024. emith_read_r_r_offs(hr2, hr, offs2);
  1025. emith_ror(hr2, hr2, 16);
  1026. break;
  1027. }
  1028. rcache_free_tmp(hr);
  1029. return hr2;
  1030. }
  1031. ram_check = 0;
  1032. }
  1033. hr = rcache_get_reg_arg(0, rs);
  1034. if (offs != 0)
  1035. emith_add_r_imm(hr, offs);
  1036. hr = emit_memhandler_read_(size, ram_check);
  1037. hr2 = rcache_get_reg(rd, RC_GR_WRITE);
  1038. if (size != 2) {
  1039. emith_sext(hr2, hr, (size == 1) ? 16 : 8);
  1040. } else
  1041. emith_move_r_r(hr2, hr);
  1042. rcache_free_tmp(hr);
  1043. return hr2;
  1044. }
  1045. static void emit_memhandler_write(int size)
  1046. {
  1047. int ctxr;
  1048. host_arg2reg(ctxr, 2);
  1049. if (reg_map_g2h[SHR_SR] != -1)
  1050. emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
  1051. rcache_clean();
  1052. switch (size) {
  1053. case 0: // 8
  1054. // XXX: consider inlining sh2_drc_write8
  1055. emith_call(sh2_drc_write8);
  1056. break;
  1057. case 1: // 16
  1058. emith_call(sh2_drc_write16);
  1059. break;
  1060. case 2: // 32
  1061. emith_move_r_r(ctxr, CONTEXT_REG);
  1062. emith_call(sh2_drc_write32);
  1063. break;
  1064. }
  1065. rcache_invalidate();
  1066. if (reg_map_g2h[SHR_SR] != -1)
  1067. emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
  1068. }
  1069. // @(Rx,Ry)
  1070. static int emit_indirect_indexed_read(int rx, int ry, int size)
  1071. {
  1072. int a0, t;
  1073. a0 = rcache_get_reg_arg(0, rx);
  1074. t = rcache_get_reg(ry, RC_GR_READ);
  1075. emith_add_r_r(a0, t);
  1076. return emit_memhandler_read(size);
  1077. }
  1078. // read @Rn, @rm
  1079. static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
  1080. {
  1081. int tmp;
  1082. rcache_get_reg_arg(0, rn);
  1083. tmp = emit_memhandler_read(size);
  1084. emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
  1085. rcache_free_tmp(tmp);
  1086. tmp = rcache_get_reg(rn, RC_GR_RMW);
  1087. emith_add_r_imm(tmp, 1 << size);
  1088. rcache_unlock(tmp);
  1089. rcache_get_reg_arg(0, rm);
  1090. *rmr = emit_memhandler_read(size);
  1091. *rnr = rcache_get_tmp();
  1092. emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
  1093. tmp = rcache_get_reg(rm, RC_GR_RMW);
  1094. emith_add_r_imm(tmp, 1 << size);
  1095. rcache_unlock(tmp);
  1096. }
  1097. static void emit_do_static_regs(int is_write, int tmpr)
  1098. {
  1099. int i, r, count;
  1100. for (i = 0; i < ARRAY_SIZE(reg_map_g2h); i++) {
  1101. r = reg_map_g2h[i];
  1102. if (r == -1)
  1103. continue;
  1104. for (count = 1; i < ARRAY_SIZE(reg_map_g2h) - 1; i++, r++) {
  1105. if (reg_map_g2h[i + 1] != r + 1)
  1106. break;
  1107. count++;
  1108. }
  1109. if (count > 1) {
  1110. // i, r point to last item
  1111. if (is_write)
  1112. emith_ctx_write_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
  1113. else
  1114. emith_ctx_read_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
  1115. } else {
  1116. if (is_write)
  1117. emith_ctx_write(r, i * 4);
  1118. else
  1119. emith_ctx_read(r, i * 4);
  1120. }
  1121. }
  1122. }
  1123. static void emit_block_entry(void)
  1124. {
  1125. int arg0;
  1126. host_arg2reg(arg0, 0);
  1127. #if (DRC_DEBUG & 8) || defined(PDB)
  1128. int arg1, arg2;
  1129. host_arg2reg(arg1, 1);
  1130. host_arg2reg(arg2, 2);
  1131. emit_do_static_regs(1, arg2);
  1132. emith_move_r_r(arg1, CONTEXT_REG);
  1133. emith_move_r_r(arg2, rcache_get_reg(SHR_SR, RC_GR_READ));
  1134. emith_call(sh2_drc_log_entry);
  1135. rcache_invalidate();
  1136. #endif
  1137. emith_tst_r_r(arg0, arg0);
  1138. EMITH_SJMP_START(DCOND_EQ);
  1139. emith_jump_reg_c(DCOND_NE, arg0);
  1140. EMITH_SJMP_END(DCOND_EQ);
  1141. }
  1142. #define DELAY_SAVE_T(sr) { \
  1143. emith_bic_r_imm(sr, T_save); \
  1144. emith_tst_r_imm(sr, T); \
  1145. EMITH_SJMP_START(DCOND_EQ); \
  1146. emith_or_r_imm_c(DCOND_NE, sr, T_save); \
  1147. EMITH_SJMP_END(DCOND_EQ); \
  1148. }
  1149. #define FLUSH_CYCLES(sr) \
  1150. if (cycles > 0) { \
  1151. emith_sub_r_imm(sr, cycles << 12); \
  1152. cycles = 0; \
  1153. }
  1154. static void *dr_get_pc_base(u32 pc, int is_slave);
  1155. static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
  1156. {
  1157. u32 branch_target_pc[MAX_LOCAL_BRANCHES];
  1158. void *branch_target_ptr[MAX_LOCAL_BRANCHES];
  1159. int branch_target_count = 0;
  1160. void *branch_patch_ptr[MAX_LOCAL_BRANCHES];
  1161. u32 branch_patch_pc[MAX_LOCAL_BRANCHES];
  1162. int branch_patch_count = 0;
  1163. u32 literal_addr[MAX_LITERALS];
  1164. int literal_addr_count = 0;
  1165. u8 op_flags[BLOCK_INSN_LIMIT];
  1166. struct {
  1167. u32 test_irq:1;
  1168. u32 pending_branch_direct:1;
  1169. u32 pending_branch_indirect:1;
  1170. u32 literals_disabled:1;
  1171. } drcf = { 0, };
  1172. // PC of current, first, last SH2 insn
  1173. u32 pc, base_pc, end_pc;
  1174. u32 end_literals;
  1175. void *block_entry_ptr;
  1176. struct block_desc *block;
  1177. u16 *dr_pc_base;
  1178. struct op_data *opd;
  1179. int blkid_main = 0;
  1180. int skip_op = 0;
  1181. u32 tmp, tmp2;
  1182. int cycles;
  1183. int i, v;
  1184. int op;
  1185. base_pc = sh2->pc;
  1186. drcf.literals_disabled = literal_disabled_frames != 0;
  1187. // get base/validate PC
  1188. dr_pc_base = dr_get_pc_base(base_pc, sh2->is_slave);
  1189. if (dr_pc_base == (void *)-1) {
  1190. printf("invalid PC, aborting: %08x\n", base_pc);
  1191. // FIXME: be less destructive
  1192. exit(1);
  1193. }
  1194. tcache_ptr = tcache_ptrs[tcache_id];
  1195. // predict tcache overflow
  1196. tmp = tcache_ptr - tcache_bases[tcache_id];
  1197. if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE) {
  1198. dbg(1, "tcache %d overflow", tcache_id);
  1199. return NULL;
  1200. }
  1201. // initial passes to disassemble and analyze the block
  1202. scan_block(base_pc, sh2->is_slave, op_flags, &end_pc, &end_literals);
  1203. if (drcf.literals_disabled)
  1204. end_literals = end_pc;
  1205. block = dr_add_block(base_pc, end_literals - base_pc,
  1206. end_pc - base_pc, sh2->is_slave, &blkid_main);
  1207. if (block == NULL)
  1208. return NULL;
  1209. block_entry_ptr = tcache_ptr;
  1210. dbg(2, "== %csh2 block #%d,%d %08x-%08x -> %p", sh2->is_slave ? 's' : 'm',
  1211. tcache_id, blkid_main, base_pc, end_pc, block_entry_ptr);
  1212. dr_link_blocks(&block->entryp[0], tcache_id);
  1213. // collect branch_targets that don't land on delay slots
  1214. for (pc = base_pc, i = 0; pc < end_pc; i++, pc += 2) {
  1215. if (!(op_flags[i] & OF_BTARGET))
  1216. continue;
  1217. if (op_flags[i] & OF_DELAY_OP) {
  1218. op_flags[i] &= ~OF_BTARGET;
  1219. continue;
  1220. }
  1221. ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc, break);
  1222. }
  1223. if (branch_target_count > 0) {
  1224. memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count);
  1225. }
  1226. // clear stale state after compile errors
  1227. rcache_invalidate();
  1228. // -------------------------------------------------
  1229. // 3rd pass: actual compilation
  1230. pc = base_pc;
  1231. cycles = 0;
  1232. for (i = 0; pc < end_pc; i++)
  1233. {
  1234. u32 delay_dep_fw = 0, delay_dep_bk = 0;
  1235. u32 tmp3, tmp4, sr;
  1236. opd = &ops[i];
  1237. op = FETCH_OP(pc);
  1238. #if (DRC_DEBUG & 2)
  1239. insns_compiled++;
  1240. #endif
  1241. #if (DRC_DEBUG & 4)
  1242. DasmSH2(sh2dasm_buff, pc, op);
  1243. printf("%c%08x %04x %s\n", (op_flags[i] & OF_BTARGET) ? '*' : ' ',
  1244. pc, op, sh2dasm_buff);
  1245. #endif
  1246. if ((op_flags[i] & OF_BTARGET) || pc == base_pc)
  1247. {
  1248. if (pc != base_pc)
  1249. {
  1250. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1251. FLUSH_CYCLES(sr);
  1252. rcache_flush();
  1253. // make block entry
  1254. v = block->entry_count;
  1255. if (v < ARRAY_SIZE(block->entryp)) {
  1256. block->entryp[v].pc = pc;
  1257. block->entryp[v].tcache_ptr = tcache_ptr;
  1258. block->entryp[v].links = NULL;
  1259. #if (DRC_DEBUG & 2)
  1260. block->entryp[v].block = block;
  1261. #endif
  1262. add_to_hashlist(&block->entryp[v], tcache_id);
  1263. block->entry_count++;
  1264. dbg(2, "-- %csh2 block #%d,%d entry %08x -> %p",
  1265. sh2->is_slave ? 's' : 'm', tcache_id, blkid_main,
  1266. pc, tcache_ptr);
  1267. // since we made a block entry, link any other blocks
  1268. // that jump to current pc
  1269. dr_link_blocks(&block->entryp[v], tcache_id);
  1270. }
  1271. else {
  1272. dbg(1, "too many entryp for block #%d,%d pc=%08x",
  1273. tcache_id, blkid_main, pc);
  1274. }
  1275. do_host_disasm(tcache_id);
  1276. }
  1277. v = find_in_array(branch_target_pc, branch_target_count, pc);
  1278. if (v >= 0)
  1279. branch_target_ptr[v] = tcache_ptr;
  1280. // must update PC
  1281. emit_move_r_imm32(SHR_PC, pc);
  1282. rcache_clean();
  1283. // check cycles
  1284. sr = rcache_get_reg(SHR_SR, RC_GR_READ);
  1285. emith_cmp_r_imm(sr, 0);
  1286. emith_jump_cond(DCOND_LE, sh2_drc_exit);
  1287. do_host_disasm(tcache_id);
  1288. rcache_unlock_all();
  1289. }
  1290. #ifdef DRC_CMP
  1291. if (!(op_flags[i] & OF_DELAY_OP)) {
  1292. emit_move_r_imm32(SHR_PC, pc);
  1293. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1294. FLUSH_CYCLES(sr);
  1295. rcache_clean();
  1296. tmp = rcache_used_hreg_mask();
  1297. emith_save_caller_regs(tmp);
  1298. emit_do_static_regs(1, 0);
  1299. emith_pass_arg_r(0, CONTEXT_REG);
  1300. emith_call(do_sh2_cmp);
  1301. emith_restore_caller_regs(tmp);
  1302. }
  1303. #endif
  1304. pc += 2;
  1305. if (skip_op > 0) {
  1306. skip_op--;
  1307. continue;
  1308. }
  1309. if (op_flags[i] & OF_DELAY_OP)
  1310. {
  1311. // handle delay slot dependencies
  1312. delay_dep_fw = opd->dest & ops[i-1].source;
  1313. delay_dep_bk = opd->source & ops[i-1].dest;
  1314. if (delay_dep_fw & BITMASK1(SHR_T)) {
  1315. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1316. DELAY_SAVE_T(sr);
  1317. }
  1318. if (delay_dep_bk & BITMASK1(SHR_PC)) {
  1319. if (opd->op != OP_LOAD_POOL && opd->op != OP_MOVA) {
  1320. // can only be those 2 really..
  1321. elprintf_sh2(sh2, EL_ANOMALY,
  1322. "drc: illegal slot insn %04x @ %08x?", op, pc - 2);
  1323. }
  1324. if (opd->imm != 0)
  1325. ; // addr already resolved somehow
  1326. else {
  1327. switch (ops[i-1].op) {
  1328. case OP_BRANCH:
  1329. emit_move_r_imm32(SHR_PC, ops[i-1].imm);
  1330. break;
  1331. case OP_BRANCH_CT:
  1332. case OP_BRANCH_CF:
  1333. tmp = rcache_get_reg(SHR_PC, RC_GR_WRITE);
  1334. sr = rcache_get_reg(SHR_SR, RC_GR_READ);
  1335. emith_move_r_imm(tmp, pc);
  1336. emith_tst_r_imm(sr, T);
  1337. tmp2 = ops[i-1].op == OP_BRANCH_CT ? DCOND_NE : DCOND_EQ;
  1338. emith_move_r_imm_c(tmp2, tmp, ops[i-1].imm);
  1339. break;
  1340. // case OP_BRANCH_R OP_BRANCH_RF - PC already loaded
  1341. }
  1342. }
  1343. }
  1344. //if (delay_dep_fw & ~BITMASK1(SHR_T))
  1345. // dbg(1, "unhandled delay_dep_fw: %x", delay_dep_fw & ~BITMASK1(SHR_T));
  1346. if (delay_dep_bk & ~BITMASK2(SHR_PC, SHR_PR))
  1347. dbg(1, "unhandled delay_dep_bk: %x", delay_dep_bk);
  1348. }
  1349. switch (opd->op)
  1350. {
  1351. case OP_BRANCH:
  1352. case OP_BRANCH_CT:
  1353. case OP_BRANCH_CF:
  1354. if (opd->dest & BITMASK1(SHR_PR))
  1355. emit_move_r_imm32(SHR_PR, pc + 2);
  1356. drcf.pending_branch_direct = 1;
  1357. goto end_op;
  1358. case OP_BRANCH_R:
  1359. if (opd->dest & BITMASK1(SHR_PR))
  1360. emit_move_r_imm32(SHR_PR, pc + 2);
  1361. emit_move_r_r(SHR_PC, opd->rm);
  1362. drcf.pending_branch_indirect = 1;
  1363. goto end_op;
  1364. case OP_BRANCH_RF:
  1365. tmp = rcache_get_reg(SHR_PC, RC_GR_WRITE);
  1366. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1367. if (opd->dest & BITMASK1(SHR_PR)) {
  1368. tmp3 = rcache_get_reg(SHR_PR, RC_GR_WRITE);
  1369. emith_move_r_imm(tmp3, pc + 2);
  1370. emith_add_r_r_r(tmp, tmp2, tmp3);
  1371. }
  1372. else {
  1373. emith_move_r_r(tmp, tmp2);
  1374. emith_add_r_imm(tmp, pc + 2);
  1375. }
  1376. drcf.pending_branch_indirect = 1;
  1377. goto end_op;
  1378. case OP_SLEEP:
  1379. printf("TODO sleep\n");
  1380. goto end_op;
  1381. case OP_RTE:
  1382. // pop PC
  1383. emit_memhandler_read_rr(SHR_PC, SHR_SP, 0, 2);
  1384. // pop SR
  1385. tmp = rcache_get_reg_arg(0, SHR_SP);
  1386. emith_add_r_imm(tmp, 4);
  1387. tmp = emit_memhandler_read(2);
  1388. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1389. emith_write_sr(sr, tmp);
  1390. rcache_free_tmp(tmp);
  1391. tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
  1392. emith_add_r_imm(tmp, 4*2);
  1393. drcf.test_irq = 1;
  1394. drcf.pending_branch_indirect = 1;
  1395. goto end_op;
  1396. case OP_LOAD_POOL:
  1397. #if PROPAGATE_CONSTANTS
  1398. if (opd->imm != 0 && opd->imm < end_literals
  1399. && literal_addr_count < MAX_LITERALS)
  1400. {
  1401. ADD_TO_ARRAY(literal_addr, literal_addr_count, opd->imm,);
  1402. if (opd->size == 2)
  1403. tmp = FETCH32(opd->imm);
  1404. else
  1405. tmp = (u32)(int)(signed short)FETCH_OP(opd->imm);
  1406. gconst_new(GET_Rn(), tmp);
  1407. }
  1408. else
  1409. #endif
  1410. {
  1411. tmp = rcache_get_tmp_arg(0);
  1412. if (opd->imm != 0)
  1413. emith_move_r_imm(tmp, opd->imm);
  1414. else {
  1415. // have to calculate read addr from PC
  1416. tmp2 = rcache_get_reg(SHR_PC, RC_GR_READ);
  1417. if (opd->size == 2) {
  1418. emith_add_r_r_imm(tmp, tmp2, 2 + (op & 0xff) * 4);
  1419. emith_bic_r_imm(tmp, 3);
  1420. }
  1421. else
  1422. emith_add_r_r_imm(tmp, tmp2, 2 + (op & 0xff) * 2);
  1423. }
  1424. tmp2 = emit_memhandler_read(opd->size);
  1425. tmp3 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
  1426. if (opd->size == 2)
  1427. emith_move_r_r(tmp3, tmp2);
  1428. else
  1429. emith_sext(tmp3, tmp2, 16);
  1430. rcache_free_tmp(tmp2);
  1431. }
  1432. goto end_op;
  1433. case OP_MOVA:
  1434. if (opd->imm != 0)
  1435. emit_move_r_imm32(SHR_R0, opd->imm);
  1436. else {
  1437. tmp = rcache_get_reg(SHR_R0, RC_GR_WRITE);
  1438. tmp2 = rcache_get_reg(SHR_PC, RC_GR_READ);
  1439. emith_add_r_r_imm(tmp, tmp2, 2 + (op & 0xff) * 4);
  1440. emith_bic_r_imm(tmp, 3);
  1441. }
  1442. goto end_op;
  1443. }
  1444. switch ((op >> 12) & 0x0f)
  1445. {
  1446. /////////////////////////////////////////////
  1447. case 0x00:
  1448. switch (op & 0x0f)
  1449. {
  1450. case 0x02:
  1451. tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
  1452. switch (GET_Fx())
  1453. {
  1454. case 0: // STC SR,Rn 0000nnnn00000010
  1455. tmp2 = SHR_SR;
  1456. break;
  1457. case 1: // STC GBR,Rn 0000nnnn00010010
  1458. tmp2 = SHR_GBR;
  1459. break;
  1460. case 2: // STC VBR,Rn 0000nnnn00100010
  1461. tmp2 = SHR_VBR;
  1462. break;
  1463. default:
  1464. goto default_;
  1465. }
  1466. tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
  1467. emith_move_r_r(tmp, tmp3);
  1468. if (tmp2 == SHR_SR)
  1469. emith_clear_msb(tmp, tmp, 22); // reserved bits defined by ISA as 0
  1470. goto end_op;
  1471. case 0x04: // MOV.B Rm,@(R0,Rn) 0000nnnnmmmm0100
  1472. case 0x05: // MOV.W Rm,@(R0,Rn) 0000nnnnmmmm0101
  1473. case 0x06: // MOV.L Rm,@(R0,Rn) 0000nnnnmmmm0110
  1474. rcache_clean();
  1475. tmp = rcache_get_reg_arg(1, GET_Rm());
  1476. tmp2 = rcache_get_reg_arg(0, SHR_R0);
  1477. tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1478. emith_add_r_r(tmp2, tmp3);
  1479. emit_memhandler_write(op & 3);
  1480. goto end_op;
  1481. case 0x07:
  1482. // MUL.L Rm,Rn 0000nnnnmmmm0111
  1483. tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1484. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1485. tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
  1486. emith_mul(tmp3, tmp2, tmp);
  1487. goto end_op;
  1488. case 0x08:
  1489. switch (GET_Fx())
  1490. {
  1491. case 0: // CLRT 0000000000001000
  1492. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1493. emith_bic_r_imm(sr, T);
  1494. break;
  1495. case 1: // SETT 0000000000011000
  1496. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1497. emith_or_r_imm(sr, T);
  1498. break;
  1499. case 2: // CLRMAC 0000000000101000
  1500. emit_move_r_imm32(SHR_MACL, 0);
  1501. emit_move_r_imm32(SHR_MACH, 0);
  1502. break;
  1503. default:
  1504. goto default_;
  1505. }
  1506. goto end_op;
  1507. case 0x09:
  1508. switch (GET_Fx())
  1509. {
  1510. case 0: // NOP 0000000000001001
  1511. break;
  1512. case 1: // DIV0U 0000000000011001
  1513. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1514. emith_bic_r_imm(sr, M|Q|T);
  1515. break;
  1516. case 2: // MOVT Rn 0000nnnn00101001
  1517. sr = rcache_get_reg(SHR_SR, RC_GR_READ);
  1518. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
  1519. emith_clear_msb(tmp2, sr, 31);
  1520. break;
  1521. default:
  1522. goto default_;
  1523. }
  1524. goto end_op;
  1525. case 0x0a:
  1526. tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
  1527. switch (GET_Fx())
  1528. {
  1529. case 0: // STS MACH,Rn 0000nnnn00001010
  1530. tmp2 = SHR_MACH;
  1531. break;
  1532. case 1: // STS MACL,Rn 0000nnnn00011010
  1533. tmp2 = SHR_MACL;
  1534. break;
  1535. case 2: // STS PR,Rn 0000nnnn00101010
  1536. tmp2 = SHR_PR;
  1537. break;
  1538. default:
  1539. goto default_;
  1540. }
  1541. tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
  1542. emith_move_r_r(tmp, tmp2);
  1543. goto end_op;
  1544. case 0x0c: // MOV.B @(R0,Rm),Rn 0000nnnnmmmm1100
  1545. case 0x0d: // MOV.W @(R0,Rm),Rn 0000nnnnmmmm1101
  1546. case 0x0e: // MOV.L @(R0,Rm),Rn 0000nnnnmmmm1110
  1547. tmp = emit_indirect_indexed_read(SHR_R0, GET_Rm(), op & 3);
  1548. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
  1549. if ((op & 3) != 2) {
  1550. emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
  1551. } else
  1552. emith_move_r_r(tmp2, tmp);
  1553. rcache_free_tmp(tmp);
  1554. goto end_op;
  1555. case 0x0f: // MAC.L @Rm+,@Rn+ 0000nnnnmmmm1111
  1556. emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2);
  1557. tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
  1558. /* MS 16 MAC bits unused if saturated */
  1559. sr = rcache_get_reg(SHR_SR, RC_GR_READ);
  1560. emith_tst_r_imm(sr, S);
  1561. EMITH_SJMP_START(DCOND_EQ);
  1562. emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16);
  1563. EMITH_SJMP_END(DCOND_EQ);
  1564. rcache_unlock(sr);
  1565. tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR
  1566. emith_mula_s64(tmp3, tmp4, tmp, tmp2);
  1567. rcache_free_tmp(tmp2);
  1568. sr = rcache_get_reg(SHR_SR, RC_GR_READ); // reget just in case
  1569. emith_tst_r_imm(sr, S);
  1570. EMITH_JMP_START(DCOND_EQ);
  1571. emith_asr(tmp, tmp4, 15);
  1572. emith_cmp_r_imm(tmp, -1); // negative overflow (0x80000000..0xffff7fff)
  1573. EMITH_SJMP_START(DCOND_GE);
  1574. emith_move_r_imm_c(DCOND_LT, tmp4, 0x8000);
  1575. emith_move_r_imm_c(DCOND_LT, tmp3, 0x0000);
  1576. EMITH_SJMP_END(DCOND_GE);
  1577. emith_cmp_r_imm(tmp, 0); // positive overflow (0x00008000..0x7fffffff)
  1578. EMITH_SJMP_START(DCOND_LE);
  1579. emith_move_r_imm_c(DCOND_GT, tmp4, 0x00007fff);
  1580. emith_move_r_imm_c(DCOND_GT, tmp3, 0xffffffff);
  1581. EMITH_SJMP_END(DCOND_LE);
  1582. EMITH_JMP_END(DCOND_EQ);
  1583. rcache_free_tmp(tmp);
  1584. goto end_op;
  1585. }
  1586. goto default_;
  1587. /////////////////////////////////////////////
  1588. case 0x01:
  1589. // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
  1590. rcache_clean();
  1591. tmp = rcache_get_reg_arg(0, GET_Rn());
  1592. tmp2 = rcache_get_reg_arg(1, GET_Rm());
  1593. if (op & 0x0f)
  1594. emith_add_r_imm(tmp, (op & 0x0f) * 4);
  1595. emit_memhandler_write(2);
  1596. goto end_op;
  1597. case 0x02:
  1598. switch (op & 0x0f)
  1599. {
  1600. case 0x00: // MOV.B Rm,@Rn 0010nnnnmmmm0000
  1601. case 0x01: // MOV.W Rm,@Rn 0010nnnnmmmm0001
  1602. case 0x02: // MOV.L Rm,@Rn 0010nnnnmmmm0010
  1603. rcache_clean();
  1604. rcache_get_reg_arg(0, GET_Rn());
  1605. rcache_get_reg_arg(1, GET_Rm());
  1606. emit_memhandler_write(op & 3);
  1607. goto end_op;
  1608. case 0x04: // MOV.B Rm,@-Rn 0010nnnnmmmm0100
  1609. case 0x05: // MOV.W Rm,@-Rn 0010nnnnmmmm0101
  1610. case 0x06: // MOV.L Rm,@-Rn 0010nnnnmmmm0110
  1611. rcache_get_reg_arg(1, GET_Rm()); // for Rm == Rn
  1612. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1613. emith_sub_r_imm(tmp, (1 << (op & 3)));
  1614. rcache_clean();
  1615. rcache_get_reg_arg(0, GET_Rn());
  1616. emit_memhandler_write(op & 3);
  1617. goto end_op;
  1618. case 0x07: // DIV0S Rm,Rn 0010nnnnmmmm0111
  1619. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1620. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1621. tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1622. emith_bic_r_imm(sr, M|Q|T);
  1623. emith_tst_r_imm(tmp2, (1<<31));
  1624. EMITH_SJMP_START(DCOND_EQ);
  1625. emith_or_r_imm_c(DCOND_NE, sr, Q);
  1626. EMITH_SJMP_END(DCOND_EQ);
  1627. emith_tst_r_imm(tmp3, (1<<31));
  1628. EMITH_SJMP_START(DCOND_EQ);
  1629. emith_or_r_imm_c(DCOND_NE, sr, M);
  1630. EMITH_SJMP_END(DCOND_EQ);
  1631. emith_teq_r_r(tmp2, tmp3);
  1632. EMITH_SJMP_START(DCOND_PL);
  1633. emith_or_r_imm_c(DCOND_MI, sr, T);
  1634. EMITH_SJMP_END(DCOND_PL);
  1635. goto end_op;
  1636. case 0x08: // TST Rm,Rn 0010nnnnmmmm1000
  1637. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1638. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1639. tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1640. emith_bic_r_imm(sr, T);
  1641. emith_tst_r_r(tmp2, tmp3);
  1642. emit_or_t_if_eq(sr);
  1643. goto end_op;
  1644. case 0x09: // AND Rm,Rn 0010nnnnmmmm1001
  1645. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1646. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1647. emith_and_r_r(tmp, tmp2);
  1648. goto end_op;
  1649. case 0x0a: // XOR Rm,Rn 0010nnnnmmmm1010
  1650. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1651. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1652. emith_eor_r_r(tmp, tmp2);
  1653. goto end_op;
  1654. case 0x0b: // OR Rm,Rn 0010nnnnmmmm1011
  1655. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1656. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1657. emith_or_r_r(tmp, tmp2);
  1658. goto end_op;
  1659. case 0x0c: // CMP/STR Rm,Rn 0010nnnnmmmm1100
  1660. tmp = rcache_get_tmp();
  1661. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1662. tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1663. emith_eor_r_r_r(tmp, tmp2, tmp3);
  1664. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1665. emith_bic_r_imm(sr, T);
  1666. emith_tst_r_imm(tmp, 0x000000ff);
  1667. emit_or_t_if_eq(sr);
  1668. emith_tst_r_imm(tmp, 0x0000ff00);
  1669. emit_or_t_if_eq(sr);
  1670. emith_tst_r_imm(tmp, 0x00ff0000);
  1671. emit_or_t_if_eq(sr);
  1672. emith_tst_r_imm(tmp, 0xff000000);
  1673. emit_or_t_if_eq(sr);
  1674. rcache_free_tmp(tmp);
  1675. goto end_op;
  1676. case 0x0d: // XTRCT Rm,Rn 0010nnnnmmmm1101
  1677. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1678. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1679. emith_lsr(tmp, tmp, 16);
  1680. emith_or_r_r_lsl(tmp, tmp2, 16);
  1681. goto end_op;
  1682. case 0x0e: // MULU.W Rm,Rn 0010nnnnmmmm1110
  1683. case 0x0f: // MULS.W Rm,Rn 0010nnnnmmmm1111
  1684. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1685. tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
  1686. if (op & 1) {
  1687. emith_sext(tmp, tmp2, 16);
  1688. } else
  1689. emith_clear_msb(tmp, tmp2, 16);
  1690. tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1691. tmp2 = rcache_get_tmp();
  1692. if (op & 1) {
  1693. emith_sext(tmp2, tmp3, 16);
  1694. } else
  1695. emith_clear_msb(tmp2, tmp3, 16);
  1696. emith_mul(tmp, tmp, tmp2);
  1697. rcache_free_tmp(tmp2);
  1698. goto end_op;
  1699. }
  1700. goto default_;
  1701. /////////////////////////////////////////////
  1702. case 0x03:
  1703. switch (op & 0x0f)
  1704. {
  1705. case 0x00: // CMP/EQ Rm,Rn 0011nnnnmmmm0000
  1706. case 0x02: // CMP/HS Rm,Rn 0011nnnnmmmm0010
  1707. case 0x03: // CMP/GE Rm,Rn 0011nnnnmmmm0011
  1708. case 0x06: // CMP/HI Rm,Rn 0011nnnnmmmm0110
  1709. case 0x07: // CMP/GT Rm,Rn 0011nnnnmmmm0111
  1710. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1711. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1712. tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1713. emith_bic_r_imm(sr, T);
  1714. emith_cmp_r_r(tmp2, tmp3);
  1715. switch (op & 0x07)
  1716. {
  1717. case 0x00: // CMP/EQ
  1718. emit_or_t_if_eq(sr);
  1719. break;
  1720. case 0x02: // CMP/HS
  1721. EMITH_SJMP_START(DCOND_LO);
  1722. emith_or_r_imm_c(DCOND_HS, sr, T);
  1723. EMITH_SJMP_END(DCOND_LO);
  1724. break;
  1725. case 0x03: // CMP/GE
  1726. EMITH_SJMP_START(DCOND_LT);
  1727. emith_or_r_imm_c(DCOND_GE, sr, T);
  1728. EMITH_SJMP_END(DCOND_LT);
  1729. break;
  1730. case 0x06: // CMP/HI
  1731. EMITH_SJMP_START(DCOND_LS);
  1732. emith_or_r_imm_c(DCOND_HI, sr, T);
  1733. EMITH_SJMP_END(DCOND_LS);
  1734. break;
  1735. case 0x07: // CMP/GT
  1736. EMITH_SJMP_START(DCOND_LE);
  1737. emith_or_r_imm_c(DCOND_GT, sr, T);
  1738. EMITH_SJMP_END(DCOND_LE);
  1739. break;
  1740. }
  1741. goto end_op;
  1742. case 0x04: // DIV1 Rm,Rn 0011nnnnmmmm0100
  1743. // Q1 = carry(Rn = (Rn << 1) | T)
  1744. // if Q ^ M
  1745. // Q2 = carry(Rn += Rm)
  1746. // else
  1747. // Q2 = carry(Rn -= Rm)
  1748. // Q = M ^ Q1 ^ Q2
  1749. // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2)
  1750. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1751. tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1752. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1753. emith_tpop_carry(sr, 0);
  1754. emith_adcf_r_r(tmp2, tmp2);
  1755. emith_tpush_carry(sr, 0); // keep Q1 in T for now
  1756. tmp4 = rcache_get_tmp();
  1757. emith_and_r_r_imm(tmp4, sr, M);
  1758. emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M
  1759. rcache_free_tmp(tmp4);
  1760. // add or sub, invert T if carry to get Q1 ^ Q2
  1761. // in: (Q ^ M) passed in Q, Q1 in T
  1762. emith_sh2_div1_step(tmp2, tmp3, sr);
  1763. emith_bic_r_imm(sr, Q);
  1764. emith_tst_r_imm(sr, M);
  1765. EMITH_SJMP_START(DCOND_EQ);
  1766. emith_or_r_imm_c(DCOND_NE, sr, Q); // Q = M
  1767. EMITH_SJMP_END(DCOND_EQ);
  1768. emith_tst_r_imm(sr, T);
  1769. EMITH_SJMP_START(DCOND_EQ);
  1770. emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2
  1771. EMITH_SJMP_END(DCOND_EQ);
  1772. emith_eor_r_imm(sr, T); // T = !(Q1 ^ Q2)
  1773. goto end_op;
  1774. case 0x05: // DMULU.L Rm,Rn 0011nnnnmmmm0101
  1775. tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1776. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1777. tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
  1778. tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
  1779. emith_mul_u64(tmp3, tmp4, tmp, tmp2);
  1780. goto end_op;
  1781. case 0x08: // SUB Rm,Rn 0011nnnnmmmm1000
  1782. case 0x0c: // ADD Rm,Rn 0011nnnnmmmm1100
  1783. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1784. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1785. if (op & 4) {
  1786. emith_add_r_r(tmp, tmp2);
  1787. } else
  1788. emith_sub_r_r(tmp, tmp2);
  1789. goto end_op;
  1790. case 0x0a: // SUBC Rm,Rn 0011nnnnmmmm1010
  1791. case 0x0e: // ADDC Rm,Rn 0011nnnnmmmm1110
  1792. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1793. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1794. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1795. if (op & 4) { // adc
  1796. emith_tpop_carry(sr, 0);
  1797. emith_adcf_r_r(tmp, tmp2);
  1798. emith_tpush_carry(sr, 0);
  1799. } else {
  1800. emith_tpop_carry(sr, 1);
  1801. emith_sbcf_r_r(tmp, tmp2);
  1802. emith_tpush_carry(sr, 1);
  1803. }
  1804. goto end_op;
  1805. case 0x0b: // SUBV Rm,Rn 0011nnnnmmmm1011
  1806. case 0x0f: // ADDV Rm,Rn 0011nnnnmmmm1111
  1807. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1808. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1809. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1810. emith_bic_r_imm(sr, T);
  1811. if (op & 4) {
  1812. emith_addf_r_r(tmp, tmp2);
  1813. } else
  1814. emith_subf_r_r(tmp, tmp2);
  1815. EMITH_SJMP_START(DCOND_VC);
  1816. emith_or_r_imm_c(DCOND_VS, sr, T);
  1817. EMITH_SJMP_END(DCOND_VC);
  1818. goto end_op;
  1819. case 0x0d: // DMULS.L Rm,Rn 0011nnnnmmmm1101
  1820. tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1821. tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
  1822. tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
  1823. tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
  1824. emith_mul_s64(tmp3, tmp4, tmp, tmp2);
  1825. goto end_op;
  1826. }
  1827. goto default_;
  1828. /////////////////////////////////////////////
  1829. case 0x04:
  1830. switch (op & 0x0f)
  1831. {
  1832. case 0x00:
  1833. switch (GET_Fx())
  1834. {
  1835. case 0: // SHLL Rn 0100nnnn00000000
  1836. case 2: // SHAL Rn 0100nnnn00100000
  1837. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1838. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1839. emith_tpop_carry(sr, 0); // dummy
  1840. emith_lslf(tmp, tmp, 1);
  1841. emith_tpush_carry(sr, 0);
  1842. goto end_op;
  1843. case 1: // DT Rn 0100nnnn00010000
  1844. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1845. #if 0 // scheduling needs tuning
  1846. if (FETCH_OP(pc) == 0x8bfd) { // BF #-2
  1847. if (gconst_get(GET_Rn(), &tmp)) {
  1848. // XXX: limit burned cycles
  1849. emit_move_r_imm32(GET_Rn(), 0);
  1850. emith_or_r_imm(sr, T);
  1851. cycles += tmp * 4 + 1; // +1 syncs with noconst version, not sure why
  1852. skip_op = 1;
  1853. }
  1854. else
  1855. emith_sh2_dtbf_loop();
  1856. goto end_op;
  1857. }
  1858. #endif
  1859. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1860. emith_bic_r_imm(sr, T);
  1861. emith_subf_r_imm(tmp, 1);
  1862. emit_or_t_if_eq(sr);
  1863. goto end_op;
  1864. }
  1865. goto default_;
  1866. case 0x01:
  1867. switch (GET_Fx())
  1868. {
  1869. case 0: // SHLR Rn 0100nnnn00000001
  1870. case 2: // SHAR Rn 0100nnnn00100001
  1871. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1872. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1873. emith_tpop_carry(sr, 0); // dummy
  1874. if (op & 0x20) {
  1875. emith_asrf(tmp, tmp, 1);
  1876. } else
  1877. emith_lsrf(tmp, tmp, 1);
  1878. emith_tpush_carry(sr, 0);
  1879. goto end_op;
  1880. case 1: // CMP/PZ Rn 0100nnnn00010001
  1881. tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
  1882. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1883. emith_bic_r_imm(sr, T);
  1884. emith_cmp_r_imm(tmp, 0);
  1885. EMITH_SJMP_START(DCOND_LT);
  1886. emith_or_r_imm_c(DCOND_GE, sr, T);
  1887. EMITH_SJMP_END(DCOND_LT);
  1888. goto end_op;
  1889. }
  1890. goto default_;
  1891. case 0x02:
  1892. case 0x03:
  1893. switch (op & 0x3f)
  1894. {
  1895. case 0x02: // STS.L MACH,@-Rn 0100nnnn00000010
  1896. tmp = SHR_MACH;
  1897. break;
  1898. case 0x12: // STS.L MACL,@-Rn 0100nnnn00010010
  1899. tmp = SHR_MACL;
  1900. break;
  1901. case 0x22: // STS.L PR,@-Rn 0100nnnn00100010
  1902. tmp = SHR_PR;
  1903. break;
  1904. case 0x03: // STC.L SR,@-Rn 0100nnnn00000011
  1905. tmp = SHR_SR;
  1906. break;
  1907. case 0x13: // STC.L GBR,@-Rn 0100nnnn00010011
  1908. tmp = SHR_GBR;
  1909. break;
  1910. case 0x23: // STC.L VBR,@-Rn 0100nnnn00100011
  1911. tmp = SHR_VBR;
  1912. break;
  1913. default:
  1914. goto default_;
  1915. }
  1916. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1917. emith_sub_r_imm(tmp2, 4);
  1918. rcache_clean();
  1919. rcache_get_reg_arg(0, GET_Rn());
  1920. tmp3 = rcache_get_reg_arg(1, tmp);
  1921. if (tmp == SHR_SR)
  1922. emith_clear_msb(tmp3, tmp3, 22); // reserved bits defined by ISA as 0
  1923. emit_memhandler_write(2);
  1924. goto end_op;
  1925. case 0x04:
  1926. case 0x05:
  1927. switch (op & 0x3f)
  1928. {
  1929. case 0x04: // ROTL Rn 0100nnnn00000100
  1930. case 0x05: // ROTR Rn 0100nnnn00000101
  1931. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1932. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1933. emith_tpop_carry(sr, 0); // dummy
  1934. if (op & 1) {
  1935. emith_rorf(tmp, tmp, 1);
  1936. } else
  1937. emith_rolf(tmp, tmp, 1);
  1938. emith_tpush_carry(sr, 0);
  1939. goto end_op;
  1940. case 0x24: // ROTCL Rn 0100nnnn00100100
  1941. case 0x25: // ROTCR Rn 0100nnnn00100101
  1942. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1943. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1944. emith_tpop_carry(sr, 0);
  1945. if (op & 1) {
  1946. emith_rorcf(tmp);
  1947. } else
  1948. emith_rolcf(tmp);
  1949. emith_tpush_carry(sr, 0);
  1950. goto end_op;
  1951. case 0x15: // CMP/PL Rn 0100nnnn00010101
  1952. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1953. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1954. emith_bic_r_imm(sr, T);
  1955. emith_cmp_r_imm(tmp, 0);
  1956. EMITH_SJMP_START(DCOND_LE);
  1957. emith_or_r_imm_c(DCOND_GT, sr, T);
  1958. EMITH_SJMP_END(DCOND_LE);
  1959. goto end_op;
  1960. }
  1961. goto default_;
  1962. case 0x06:
  1963. case 0x07:
  1964. switch (op & 0x3f)
  1965. {
  1966. case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
  1967. tmp = SHR_MACH;
  1968. break;
  1969. case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
  1970. tmp = SHR_MACL;
  1971. break;
  1972. case 0x26: // LDS.L @Rm+,PR 0100mmmm00100110
  1973. tmp = SHR_PR;
  1974. break;
  1975. case 0x07: // LDC.L @Rm+,SR 0100mmmm00000111
  1976. tmp = SHR_SR;
  1977. break;
  1978. case 0x17: // LDC.L @Rm+,GBR 0100mmmm00010111
  1979. tmp = SHR_GBR;
  1980. break;
  1981. case 0x27: // LDC.L @Rm+,VBR 0100mmmm00100111
  1982. tmp = SHR_VBR;
  1983. break;
  1984. default:
  1985. goto default_;
  1986. }
  1987. rcache_get_reg_arg(0, GET_Rn());
  1988. tmp2 = emit_memhandler_read(2);
  1989. if (tmp == SHR_SR) {
  1990. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  1991. emith_write_sr(sr, tmp2);
  1992. drcf.test_irq = 1;
  1993. } else {
  1994. tmp = rcache_get_reg(tmp, RC_GR_WRITE);
  1995. emith_move_r_r(tmp, tmp2);
  1996. }
  1997. rcache_free_tmp(tmp2);
  1998. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  1999. emith_add_r_imm(tmp, 4);
  2000. goto end_op;
  2001. case 0x08:
  2002. case 0x09:
  2003. switch (GET_Fx())
  2004. {
  2005. case 0:
  2006. // SHLL2 Rn 0100nnnn00001000
  2007. // SHLR2 Rn 0100nnnn00001001
  2008. tmp = 2;
  2009. break;
  2010. case 1:
  2011. // SHLL8 Rn 0100nnnn00011000
  2012. // SHLR8 Rn 0100nnnn00011001
  2013. tmp = 8;
  2014. break;
  2015. case 2:
  2016. // SHLL16 Rn 0100nnnn00101000
  2017. // SHLR16 Rn 0100nnnn00101001
  2018. tmp = 16;
  2019. break;
  2020. default:
  2021. goto default_;
  2022. }
  2023. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  2024. if (op & 1) {
  2025. emith_lsr(tmp2, tmp2, tmp);
  2026. } else
  2027. emith_lsl(tmp2, tmp2, tmp);
  2028. goto end_op;
  2029. case 0x0a:
  2030. switch (GET_Fx())
  2031. {
  2032. case 0: // LDS Rm,MACH 0100mmmm00001010
  2033. tmp2 = SHR_MACH;
  2034. break;
  2035. case 1: // LDS Rm,MACL 0100mmmm00011010
  2036. tmp2 = SHR_MACL;
  2037. break;
  2038. case 2: // LDS Rm,PR 0100mmmm00101010
  2039. tmp2 = SHR_PR;
  2040. break;
  2041. default:
  2042. goto default_;
  2043. }
  2044. emit_move_r_r(tmp2, GET_Rn());
  2045. goto end_op;
  2046. case 0x0b:
  2047. switch (GET_Fx())
  2048. {
  2049. case 1: // TAS.B @Rn 0100nnnn00011011
  2050. // XXX: is TAS working on 32X?
  2051. rcache_get_reg_arg(0, GET_Rn());
  2052. tmp = emit_memhandler_read(0);
  2053. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2054. emith_bic_r_imm(sr, T);
  2055. emith_cmp_r_imm(tmp, 0);
  2056. emit_or_t_if_eq(sr);
  2057. rcache_clean();
  2058. emith_or_r_imm(tmp, 0x80);
  2059. tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp
  2060. emith_move_r_r(tmp2, tmp);
  2061. rcache_free_tmp(tmp);
  2062. rcache_get_reg_arg(0, GET_Rn());
  2063. emit_memhandler_write(0);
  2064. break;
  2065. default:
  2066. goto default_;
  2067. }
  2068. goto end_op;
  2069. case 0x0e:
  2070. tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
  2071. switch (GET_Fx())
  2072. {
  2073. case 0: // LDC Rm,SR 0100mmmm00001110
  2074. tmp2 = SHR_SR;
  2075. break;
  2076. case 1: // LDC Rm,GBR 0100mmmm00011110
  2077. tmp2 = SHR_GBR;
  2078. break;
  2079. case 2: // LDC Rm,VBR 0100mmmm00101110
  2080. tmp2 = SHR_VBR;
  2081. break;
  2082. default:
  2083. goto default_;
  2084. }
  2085. if (tmp2 == SHR_SR) {
  2086. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2087. emith_write_sr(sr, tmp);
  2088. drcf.test_irq = 1;
  2089. } else {
  2090. tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
  2091. emith_move_r_r(tmp2, tmp);
  2092. }
  2093. goto end_op;
  2094. case 0x0f:
  2095. // MAC.W @Rm+,@Rn+ 0100nnnnmmmm1111
  2096. emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
  2097. emith_sext(tmp, tmp, 16);
  2098. emith_sext(tmp2, tmp2, 16);
  2099. tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
  2100. tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
  2101. emith_mula_s64(tmp3, tmp4, tmp, tmp2);
  2102. rcache_free_tmp(tmp2);
  2103. // XXX: MACH should be untouched when S is set?
  2104. sr = rcache_get_reg(SHR_SR, RC_GR_READ);
  2105. emith_tst_r_imm(sr, S);
  2106. EMITH_JMP_START(DCOND_EQ);
  2107. emith_asr(tmp, tmp3, 31);
  2108. emith_eorf_r_r(tmp, tmp4); // tmp = ((signed)macl >> 31) ^ mach
  2109. EMITH_JMP_START(DCOND_EQ);
  2110. emith_move_r_imm(tmp3, 0x80000000);
  2111. emith_tst_r_r(tmp4, tmp4);
  2112. EMITH_SJMP_START(DCOND_MI);
  2113. emith_sub_r_imm_c(DCOND_PL, tmp3, 1); // positive
  2114. EMITH_SJMP_END(DCOND_MI);
  2115. EMITH_JMP_END(DCOND_EQ);
  2116. EMITH_JMP_END(DCOND_EQ);
  2117. rcache_free_tmp(tmp);
  2118. goto end_op;
  2119. }
  2120. goto default_;
  2121. /////////////////////////////////////////////
  2122. case 0x05:
  2123. // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
  2124. emit_memhandler_read_rr(GET_Rn(), GET_Rm(), (op & 0x0f) * 4, 2);
  2125. goto end_op;
  2126. /////////////////////////////////////////////
  2127. case 0x06:
  2128. switch (op & 0x0f)
  2129. {
  2130. case 0x00: // MOV.B @Rm,Rn 0110nnnnmmmm0000
  2131. case 0x01: // MOV.W @Rm,Rn 0110nnnnmmmm0001
  2132. case 0x02: // MOV.L @Rm,Rn 0110nnnnmmmm0010
  2133. case 0x04: // MOV.B @Rm+,Rn 0110nnnnmmmm0100
  2134. case 0x05: // MOV.W @Rm+,Rn 0110nnnnmmmm0101
  2135. case 0x06: // MOV.L @Rm+,Rn 0110nnnnmmmm0110
  2136. emit_memhandler_read_rr(GET_Rn(), GET_Rm(), 0, op & 3);
  2137. if ((op & 7) >= 4 && GET_Rn() != GET_Rm()) {
  2138. tmp = rcache_get_reg(GET_Rm(), RC_GR_RMW);
  2139. emith_add_r_imm(tmp, (1 << (op & 3)));
  2140. }
  2141. goto end_op;
  2142. case 0x03:
  2143. case 0x07 ... 0x0f:
  2144. tmp = rcache_get_reg(GET_Rm(), RC_GR_READ);
  2145. tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
  2146. switch (op & 0x0f)
  2147. {
  2148. case 0x03: // MOV Rm,Rn 0110nnnnmmmm0011
  2149. emith_move_r_r(tmp2, tmp);
  2150. break;
  2151. case 0x07: // NOT Rm,Rn 0110nnnnmmmm0111
  2152. emith_mvn_r_r(tmp2, tmp);
  2153. break;
  2154. case 0x08: // SWAP.B Rm,Rn 0110nnnnmmmm1000
  2155. tmp3 = tmp2;
  2156. if (tmp == tmp2)
  2157. tmp3 = rcache_get_tmp();
  2158. tmp4 = rcache_get_tmp();
  2159. emith_lsr(tmp3, tmp, 16);
  2160. emith_or_r_r_lsl(tmp3, tmp, 24);
  2161. emith_and_r_r_imm(tmp4, tmp, 0xff00);
  2162. emith_or_r_r_lsl(tmp3, tmp4, 8);
  2163. emith_rol(tmp2, tmp3, 16);
  2164. rcache_free_tmp(tmp4);
  2165. if (tmp == tmp2)
  2166. rcache_free_tmp(tmp3);
  2167. break;
  2168. case 0x09: // SWAP.W Rm,Rn 0110nnnnmmmm1001
  2169. emith_rol(tmp2, tmp, 16);
  2170. break;
  2171. case 0x0a: // NEGC Rm,Rn 0110nnnnmmmm1010
  2172. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2173. emith_tpop_carry(sr, 1);
  2174. emith_negcf_r_r(tmp2, tmp);
  2175. emith_tpush_carry(sr, 1);
  2176. break;
  2177. case 0x0b: // NEG Rm,Rn 0110nnnnmmmm1011
  2178. emith_neg_r_r(tmp2, tmp);
  2179. break;
  2180. case 0x0c: // EXTU.B Rm,Rn 0110nnnnmmmm1100
  2181. emith_clear_msb(tmp2, tmp, 24);
  2182. break;
  2183. case 0x0d: // EXTU.W Rm,Rn 0110nnnnmmmm1101
  2184. emith_clear_msb(tmp2, tmp, 16);
  2185. break;
  2186. case 0x0e: // EXTS.B Rm,Rn 0110nnnnmmmm1110
  2187. emith_sext(tmp2, tmp, 8);
  2188. break;
  2189. case 0x0f: // EXTS.W Rm,Rn 0110nnnnmmmm1111
  2190. emith_sext(tmp2, tmp, 16);
  2191. break;
  2192. }
  2193. goto end_op;
  2194. }
  2195. goto default_;
  2196. /////////////////////////////////////////////
  2197. case 0x07:
  2198. // ADD #imm,Rn 0111nnnniiiiiiii
  2199. tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
  2200. if (op & 0x80) { // adding negative
  2201. emith_sub_r_imm(tmp, -op & 0xff);
  2202. } else
  2203. emith_add_r_imm(tmp, op & 0xff);
  2204. goto end_op;
  2205. /////////////////////////////////////////////
  2206. case 0x08:
  2207. switch (op & 0x0f00)
  2208. {
  2209. case 0x0000: // MOV.B R0,@(disp,Rn) 10000000nnnndddd
  2210. case 0x0100: // MOV.W R0,@(disp,Rn) 10000001nnnndddd
  2211. rcache_clean();
  2212. tmp = rcache_get_reg_arg(0, GET_Rm());
  2213. tmp2 = rcache_get_reg_arg(1, SHR_R0);
  2214. tmp3 = (op & 0x100) >> 8;
  2215. if (op & 0x0f)
  2216. emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
  2217. emit_memhandler_write(tmp3);
  2218. goto end_op;
  2219. case 0x0400: // MOV.B @(disp,Rm),R0 10000100mmmmdddd
  2220. case 0x0500: // MOV.W @(disp,Rm),R0 10000101mmmmdddd
  2221. tmp = (op & 0x100) >> 8;
  2222. emit_memhandler_read_rr(SHR_R0, GET_Rm(), (op & 0x0f) << tmp, tmp);
  2223. goto end_op;
  2224. case 0x0800: // CMP/EQ #imm,R0 10001000iiiiiiii
  2225. // XXX: could use cmn
  2226. tmp = rcache_get_tmp();
  2227. tmp2 = rcache_get_reg(0, RC_GR_READ);
  2228. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2229. emith_move_r_imm_s8(tmp, op & 0xff);
  2230. emith_bic_r_imm(sr, T);
  2231. emith_cmp_r_r(tmp2, tmp);
  2232. emit_or_t_if_eq(sr);
  2233. rcache_free_tmp(tmp);
  2234. goto end_op;
  2235. }
  2236. goto default_;
  2237. /////////////////////////////////////////////
  2238. case 0x0c:
  2239. switch (op & 0x0f00)
  2240. {
  2241. case 0x0000: // MOV.B R0,@(disp,GBR) 11000000dddddddd
  2242. case 0x0100: // MOV.W R0,@(disp,GBR) 11000001dddddddd
  2243. case 0x0200: // MOV.L R0,@(disp,GBR) 11000010dddddddd
  2244. rcache_clean();
  2245. tmp = rcache_get_reg_arg(0, SHR_GBR);
  2246. tmp2 = rcache_get_reg_arg(1, SHR_R0);
  2247. tmp3 = (op & 0x300) >> 8;
  2248. emith_add_r_imm(tmp, (op & 0xff) << tmp3);
  2249. emit_memhandler_write(tmp3);
  2250. goto end_op;
  2251. case 0x0400: // MOV.B @(disp,GBR),R0 11000100dddddddd
  2252. case 0x0500: // MOV.W @(disp,GBR),R0 11000101dddddddd
  2253. case 0x0600: // MOV.L @(disp,GBR),R0 11000110dddddddd
  2254. tmp = (op & 0x300) >> 8;
  2255. emit_memhandler_read_rr(SHR_R0, SHR_GBR, (op & 0xff) << tmp, tmp);
  2256. goto end_op;
  2257. case 0x0300: // TRAPA #imm 11000011iiiiiiii
  2258. tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
  2259. emith_sub_r_imm(tmp, 4*2);
  2260. // push SR
  2261. tmp = rcache_get_reg_arg(0, SHR_SP);
  2262. emith_add_r_imm(tmp, 4);
  2263. tmp = rcache_get_reg_arg(1, SHR_SR);
  2264. emith_clear_msb(tmp, tmp, 22);
  2265. emit_memhandler_write(2);
  2266. // push PC
  2267. rcache_get_reg_arg(0, SHR_SP);
  2268. tmp = rcache_get_tmp_arg(1);
  2269. emith_move_r_imm(tmp, pc);
  2270. emit_memhandler_write(2);
  2271. // obtain new PC
  2272. emit_memhandler_read_rr(SHR_PC, SHR_VBR, (op & 0xff) * 4, 2);
  2273. // indirect jump -> back to dispatcher
  2274. rcache_flush();
  2275. emith_jump(sh2_drc_dispatcher);
  2276. goto end_op;
  2277. case 0x0800: // TST #imm,R0 11001000iiiiiiii
  2278. tmp = rcache_get_reg(SHR_R0, RC_GR_READ);
  2279. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2280. emith_bic_r_imm(sr, T);
  2281. emith_tst_r_imm(tmp, op & 0xff);
  2282. emit_or_t_if_eq(sr);
  2283. goto end_op;
  2284. case 0x0900: // AND #imm,R0 11001001iiiiiiii
  2285. tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
  2286. emith_and_r_imm(tmp, op & 0xff);
  2287. goto end_op;
  2288. case 0x0a00: // XOR #imm,R0 11001010iiiiiiii
  2289. tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
  2290. emith_eor_r_imm(tmp, op & 0xff);
  2291. goto end_op;
  2292. case 0x0b00: // OR #imm,R0 11001011iiiiiiii
  2293. tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
  2294. emith_or_r_imm(tmp, op & 0xff);
  2295. goto end_op;
  2296. case 0x0c00: // TST.B #imm,@(R0,GBR) 11001100iiiiiiii
  2297. tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
  2298. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2299. emith_bic_r_imm(sr, T);
  2300. emith_tst_r_imm(tmp, op & 0xff);
  2301. emit_or_t_if_eq(sr);
  2302. rcache_free_tmp(tmp);
  2303. goto end_op;
  2304. case 0x0d00: // AND.B #imm,@(R0,GBR) 11001101iiiiiiii
  2305. tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
  2306. emith_and_r_imm(tmp, op & 0xff);
  2307. goto end_rmw_op;
  2308. case 0x0e00: // XOR.B #imm,@(R0,GBR) 11001110iiiiiiii
  2309. tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
  2310. emith_eor_r_imm(tmp, op & 0xff);
  2311. goto end_rmw_op;
  2312. case 0x0f00: // OR.B #imm,@(R0,GBR) 11001111iiiiiiii
  2313. tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
  2314. emith_or_r_imm(tmp, op & 0xff);
  2315. end_rmw_op:
  2316. tmp2 = rcache_get_tmp_arg(1);
  2317. emith_move_r_r(tmp2, tmp);
  2318. rcache_free_tmp(tmp);
  2319. tmp3 = rcache_get_reg_arg(0, SHR_GBR);
  2320. tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
  2321. emith_add_r_r(tmp3, tmp4);
  2322. emit_memhandler_write(0);
  2323. goto end_op;
  2324. }
  2325. goto default_;
  2326. /////////////////////////////////////////////
  2327. case 0x0e:
  2328. // MOV #imm,Rn 1110nnnniiiiiiii
  2329. emit_move_r_imm32(GET_Rn(), (u32)(signed int)(signed char)op);
  2330. goto end_op;
  2331. default:
  2332. default_:
  2333. elprintf_sh2(sh2, EL_ANOMALY,
  2334. "drc: illegal op %04x @ %08x", op, pc - 2);
  2335. tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
  2336. emith_sub_r_imm(tmp, 4*2);
  2337. // push SR
  2338. tmp = rcache_get_reg_arg(0, SHR_SP);
  2339. emith_add_r_imm(tmp, 4);
  2340. tmp = rcache_get_reg_arg(1, SHR_SR);
  2341. emith_clear_msb(tmp, tmp, 22);
  2342. emit_memhandler_write(2);
  2343. // push PC
  2344. rcache_get_reg_arg(0, SHR_SP);
  2345. tmp = rcache_get_tmp_arg(1);
  2346. emith_move_r_imm(tmp, pc - 2);
  2347. emit_memhandler_write(2);
  2348. // obtain new PC
  2349. emit_memhandler_read_rr(SHR_PC, SHR_VBR, 4 * 4, 2);
  2350. // indirect jump -> back to dispatcher
  2351. rcache_flush();
  2352. emith_jump(sh2_drc_dispatcher);
  2353. break;
  2354. }
  2355. end_op:
  2356. rcache_unlock_all();
  2357. cycles += opd->cycles;
  2358. if (op_flags[i+1] & OF_DELAY_OP) {
  2359. do_host_disasm(tcache_id);
  2360. continue;
  2361. }
  2362. // test irq?
  2363. if (drcf.test_irq && !drcf.pending_branch_direct) {
  2364. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2365. FLUSH_CYCLES(sr);
  2366. if (!drcf.pending_branch_indirect)
  2367. emit_move_r_imm32(SHR_PC, pc);
  2368. rcache_flush();
  2369. emith_call(sh2_drc_test_irq);
  2370. drcf.test_irq = 0;
  2371. }
  2372. // branch handling (with/without delay)
  2373. if (drcf.pending_branch_direct)
  2374. {
  2375. struct op_data *opd_b =
  2376. (op_flags[i] & OF_DELAY_OP) ? &ops[i-1] : opd;
  2377. u32 target_pc = opd_b->imm;
  2378. int cond = -1;
  2379. void *target = NULL;
  2380. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2381. FLUSH_CYCLES(sr);
  2382. if (opd_b->op != OP_BRANCH)
  2383. cond = (opd_b->op == OP_BRANCH_CF) ? DCOND_EQ : DCOND_NE;
  2384. if (cond != -1) {
  2385. int ctaken = (op_flags[i] & OF_DELAY_OP) ? 1 : 2;
  2386. if (delay_dep_fw & BITMASK1(SHR_T))
  2387. emith_tst_r_imm(sr, T_save);
  2388. else
  2389. emith_tst_r_imm(sr, T);
  2390. emith_sub_r_imm_c(cond, sr, ctaken<<12);
  2391. }
  2392. rcache_clean();
  2393. #if LINK_BRANCHES
  2394. if (find_in_array(branch_target_pc, branch_target_count, target_pc) >= 0)
  2395. {
  2396. // local branch
  2397. // XXX: jumps back can be linked already
  2398. if (branch_patch_count < MAX_LOCAL_BRANCHES) {
  2399. target = tcache_ptr;
  2400. branch_patch_pc[branch_patch_count] = target_pc;
  2401. branch_patch_ptr[branch_patch_count] = target;
  2402. branch_patch_count++;
  2403. }
  2404. else
  2405. dbg(1, "warning: too many local branches");
  2406. }
  2407. if (target == NULL)
  2408. #endif
  2409. {
  2410. // can't resolve branch locally, make a block exit
  2411. emit_move_r_imm32(SHR_PC, target_pc);
  2412. rcache_clean();
  2413. target = dr_prepare_ext_branch(target_pc, sh2->is_slave, tcache_id);
  2414. if (target == NULL)
  2415. return NULL;
  2416. }
  2417. if (cond != -1)
  2418. emith_jump_cond_patchable(cond, target);
  2419. else {
  2420. emith_jump_patchable(target);
  2421. rcache_invalidate();
  2422. }
  2423. drcf.pending_branch_direct = 0;
  2424. }
  2425. else if (drcf.pending_branch_indirect) {
  2426. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2427. FLUSH_CYCLES(sr);
  2428. rcache_flush();
  2429. emith_jump(sh2_drc_dispatcher);
  2430. drcf.pending_branch_indirect = 0;
  2431. }
  2432. do_host_disasm(tcache_id);
  2433. }
  2434. tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2435. FLUSH_CYCLES(tmp);
  2436. rcache_flush();
  2437. // check the last op
  2438. if (op_flags[i-1] & OF_DELAY_OP)
  2439. opd = &ops[i-2];
  2440. else
  2441. opd = &ops[i-1];
  2442. if (opd->op != OP_BRANCH && opd->op != OP_BRANCH_R
  2443. && opd->op != OP_BRANCH_RF && opd->op != OP_RTE)
  2444. {
  2445. void *target;
  2446. emit_move_r_imm32(SHR_PC, pc);
  2447. rcache_flush();
  2448. target = dr_prepare_ext_branch(pc, sh2->is_slave, tcache_id);
  2449. if (target == NULL)
  2450. return NULL;
  2451. emith_jump_patchable(target);
  2452. }
  2453. // link local branches
  2454. for (i = 0; i < branch_patch_count; i++) {
  2455. void *target;
  2456. int t;
  2457. t = find_in_array(branch_target_pc, branch_target_count, branch_patch_pc[i]);
  2458. target = branch_target_ptr[t];
  2459. if (target == NULL) {
  2460. // flush pc and go back to dispatcher (this should no longer happen)
  2461. dbg(1, "stray branch to %08x %p", branch_patch_pc[i], tcache_ptr);
  2462. target = tcache_ptr;
  2463. emit_move_r_imm32(SHR_PC, branch_patch_pc[i]);
  2464. rcache_flush();
  2465. emith_jump(sh2_drc_dispatcher);
  2466. }
  2467. emith_jump_patch(branch_patch_ptr[i], target);
  2468. }
  2469. // mark memory blocks as containing compiled code
  2470. // override any overlay blocks as they become unreachable anyway
  2471. if ((block->addr & 0xc7fc0000) == 0x06000000
  2472. || (block->addr & 0xfffff000) == 0xc0000000)
  2473. {
  2474. u16 *drc_ram_blk = NULL;
  2475. u32 addr, mask = 0, shift = 0;
  2476. if (tcache_id != 0) {
  2477. // data array, BIOS
  2478. drc_ram_blk = Pico32xMem->drcblk_da[sh2->is_slave];
  2479. shift = SH2_DRCBLK_DA_SHIFT;
  2480. mask = 0xfff;
  2481. }
  2482. else {
  2483. // SDRAM
  2484. drc_ram_blk = Pico32xMem->drcblk_ram;
  2485. shift = SH2_DRCBLK_RAM_SHIFT;
  2486. mask = 0x3ffff;
  2487. }
  2488. // mark recompiled insns
  2489. drc_ram_blk[(base_pc & mask) >> shift] = 1;
  2490. for (pc = base_pc; pc < end_pc; pc += 2)
  2491. drc_ram_blk[(pc & mask) >> shift] = 1;
  2492. // mark literals
  2493. for (i = 0; i < literal_addr_count; i++) {
  2494. tmp = literal_addr[i];
  2495. drc_ram_blk[(tmp & mask) >> shift] = 1;
  2496. }
  2497. // add to invalidation lookup lists
  2498. addr = base_pc & ~(INVAL_PAGE_SIZE - 1);
  2499. for (; addr < end_literals; addr += INVAL_PAGE_SIZE) {
  2500. i = (addr & mask) / INVAL_PAGE_SIZE;
  2501. add_to_block_list(&inval_lookup[tcache_id][i], block);
  2502. }
  2503. }
  2504. tcache_ptrs[tcache_id] = tcache_ptr;
  2505. host_instructions_updated(block_entry_ptr, tcache_ptr);
  2506. do_host_disasm(tcache_id);
  2507. if (drcf.literals_disabled && literal_addr_count)
  2508. dbg(1, "literals_disabled && literal_addr_count?");
  2509. dbg(2, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
  2510. tcache_id, blkid_main,
  2511. tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
  2512. insns_compiled, host_insn_count, (float)host_insn_count / insns_compiled);
  2513. if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
  2514. dbg(2, " hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
  2515. /*
  2516. printf("~~~\n");
  2517. tcache_dsm_ptrs[tcache_id] = block_entry_ptr;
  2518. do_host_disasm(tcache_id);
  2519. printf("~~~\n");
  2520. */
  2521. #if (DRC_DEBUG & 4)
  2522. fflush(stdout);
  2523. #endif
  2524. return block_entry_ptr;
  2525. }
  2526. static void sh2_generate_utils(void)
  2527. {
  2528. int arg0, arg1, arg2, sr, tmp;
  2529. sh2_drc_write32 = p32x_sh2_write32;
  2530. sh2_drc_read8 = p32x_sh2_read8;
  2531. sh2_drc_read16 = p32x_sh2_read16;
  2532. sh2_drc_read32 = p32x_sh2_read32;
  2533. host_arg2reg(arg0, 0);
  2534. host_arg2reg(arg1, 1);
  2535. host_arg2reg(arg2, 2);
  2536. emith_move_r_r(arg0, arg0); // nop
  2537. // sh2_drc_exit(void)
  2538. sh2_drc_exit = (void *)tcache_ptr;
  2539. emit_do_static_regs(1, arg2);
  2540. emith_sh2_drc_exit();
  2541. // sh2_drc_dispatcher(void)
  2542. sh2_drc_dispatcher = (void *)tcache_ptr;
  2543. sr = rcache_get_reg(SHR_SR, RC_GR_READ);
  2544. emith_cmp_r_imm(sr, 0);
  2545. emith_jump_cond(DCOND_LT, sh2_drc_exit);
  2546. rcache_invalidate();
  2547. emith_ctx_read(arg0, SHR_PC * 4);
  2548. emith_ctx_read(arg1, offsetof(SH2, is_slave));
  2549. emith_add_r_r_imm(arg2, CONTEXT_REG, offsetof(SH2, drc_tmp));
  2550. emith_call(dr_lookup_block);
  2551. emit_block_entry();
  2552. // lookup failed, call sh2_translate()
  2553. emith_move_r_r(arg0, CONTEXT_REG);
  2554. emith_ctx_read(arg1, offsetof(SH2, drc_tmp)); // tcache_id
  2555. emith_call(sh2_translate);
  2556. emit_block_entry();
  2557. // sh2_translate() failed, flush cache and retry
  2558. emith_ctx_read(arg0, offsetof(SH2, drc_tmp));
  2559. emith_call(flush_tcache);
  2560. emith_move_r_r(arg0, CONTEXT_REG);
  2561. emith_ctx_read(arg1, offsetof(SH2, drc_tmp));
  2562. emith_call(sh2_translate);
  2563. emit_block_entry();
  2564. // XXX: can't translate, fail
  2565. emith_call(dr_failure);
  2566. // sh2_drc_test_irq(void)
  2567. // assumes it's called from main function (may jump to dispatcher)
  2568. sh2_drc_test_irq = (void *)tcache_ptr;
  2569. emith_ctx_read(arg1, offsetof(SH2, pending_level));
  2570. sr = rcache_get_reg(SHR_SR, RC_GR_READ);
  2571. emith_lsr(arg0, sr, I_SHIFT);
  2572. emith_and_r_imm(arg0, 0x0f);
  2573. emith_cmp_r_r(arg1, arg0); // pending_level > ((sr >> 4) & 0x0f)?
  2574. EMITH_SJMP_START(DCOND_GT);
  2575. emith_ret_c(DCOND_LE); // nope, return
  2576. EMITH_SJMP_END(DCOND_GT);
  2577. // adjust SP
  2578. tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
  2579. emith_sub_r_imm(tmp, 4*2);
  2580. rcache_clean();
  2581. // push SR
  2582. tmp = rcache_get_reg_arg(0, SHR_SP);
  2583. emith_add_r_imm(tmp, 4);
  2584. tmp = rcache_get_reg_arg(1, SHR_SR);
  2585. emith_clear_msb(tmp, tmp, 22);
  2586. emith_move_r_r(arg2, CONTEXT_REG);
  2587. emith_call(p32x_sh2_write32); // XXX: use sh2_drc_write32?
  2588. rcache_invalidate();
  2589. // push PC
  2590. rcache_get_reg_arg(0, SHR_SP);
  2591. emith_ctx_read(arg1, SHR_PC * 4);
  2592. emith_move_r_r(arg2, CONTEXT_REG);
  2593. emith_call(p32x_sh2_write32);
  2594. rcache_invalidate();
  2595. // update I, cycles, do callback
  2596. emith_ctx_read(arg1, offsetof(SH2, pending_level));
  2597. sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
  2598. emith_bic_r_imm(sr, I);
  2599. emith_or_r_r_lsl(sr, arg1, I_SHIFT);
  2600. emith_sub_r_imm(sr, 13 << 12); // at least 13 cycles
  2601. rcache_flush();
  2602. emith_move_r_r(arg0, CONTEXT_REG);
  2603. emith_call_ctx(offsetof(SH2, irq_callback)); // vector = sh2->irq_callback(sh2, level);
  2604. // obtain new PC
  2605. emith_lsl(arg0, arg0, 2);
  2606. emith_ctx_read(arg1, SHR_VBR * 4);
  2607. emith_add_r_r(arg0, arg1);
  2608. emit_memhandler_read(2);
  2609. emith_ctx_write(arg0, SHR_PC * 4);
  2610. #ifdef __i386__
  2611. emith_add_r_imm(xSP, 4); // fix stack
  2612. #endif
  2613. emith_jump(sh2_drc_dispatcher);
  2614. rcache_invalidate();
  2615. // sh2_drc_entry(SH2 *sh2)
  2616. sh2_drc_entry = (void *)tcache_ptr;
  2617. emith_sh2_drc_entry();
  2618. emith_move_r_r(CONTEXT_REG, arg0); // move ctx, arg0
  2619. emit_do_static_regs(0, arg2);
  2620. emith_call(sh2_drc_test_irq);
  2621. emith_jump(sh2_drc_dispatcher);
  2622. // sh2_drc_write8(u32 a, u32 d)
  2623. sh2_drc_write8 = (void *)tcache_ptr;
  2624. emith_ctx_read(arg2, offsetof(SH2, write8_tab));
  2625. emith_sh2_wcall(arg0, arg2);
  2626. // sh2_drc_write16(u32 a, u32 d)
  2627. sh2_drc_write16 = (void *)tcache_ptr;
  2628. emith_ctx_read(arg2, offsetof(SH2, write16_tab));
  2629. emith_sh2_wcall(arg0, arg2);
  2630. #ifdef PDB_NET
  2631. // debug
  2632. #define MAKE_READ_WRAPPER(func) { \
  2633. void *tmp = (void *)tcache_ptr; \
  2634. emith_push_ret(); \
  2635. emith_call(func); \
  2636. emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0])); \
  2637. emith_addf_r_r(arg2, arg0); \
  2638. emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
  2639. emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1])); \
  2640. emith_adc_r_imm(arg2, 0x01000000); \
  2641. emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
  2642. emith_pop_and_ret(); \
  2643. func = tmp; \
  2644. }
  2645. #define MAKE_WRITE_WRAPPER(func) { \
  2646. void *tmp = (void *)tcache_ptr; \
  2647. emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0])); \
  2648. emith_addf_r_r(arg2, arg1); \
  2649. emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
  2650. emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1])); \
  2651. emith_adc_r_imm(arg2, 0x01000000); \
  2652. emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
  2653. emith_move_r_r(arg2, CONTEXT_REG); \
  2654. emith_jump(func); \
  2655. func = tmp; \
  2656. }
  2657. MAKE_READ_WRAPPER(sh2_drc_read8);
  2658. MAKE_READ_WRAPPER(sh2_drc_read16);
  2659. MAKE_READ_WRAPPER(sh2_drc_read32);
  2660. MAKE_WRITE_WRAPPER(sh2_drc_write8);
  2661. MAKE_WRITE_WRAPPER(sh2_drc_write16);
  2662. MAKE_WRITE_WRAPPER(sh2_drc_write32);
  2663. #if (DRC_DEBUG & 4)
  2664. host_dasm_new_symbol(sh2_drc_read8);
  2665. host_dasm_new_symbol(sh2_drc_read16);
  2666. host_dasm_new_symbol(sh2_drc_read32);
  2667. host_dasm_new_symbol(sh2_drc_write32);
  2668. #endif
  2669. #endif
  2670. rcache_invalidate();
  2671. #if (DRC_DEBUG & 4)
  2672. host_dasm_new_symbol(sh2_drc_entry);
  2673. host_dasm_new_symbol(sh2_drc_dispatcher);
  2674. host_dasm_new_symbol(sh2_drc_exit);
  2675. host_dasm_new_symbol(sh2_drc_test_irq);
  2676. host_dasm_new_symbol(sh2_drc_write8);
  2677. host_dasm_new_symbol(sh2_drc_write16);
  2678. #endif
  2679. }
  2680. static void sh2_smc_rm_block_entry(struct block_desc *bd, int tcache_id, u32 ram_mask)
  2681. {
  2682. struct block_link *bl, *bl_next, *bl_unresolved;
  2683. u32 i, addr, end_addr;
  2684. void *tmp;
  2685. dbg(2, " killing entry %08x-%08x-%08x, blkid %d,%d",
  2686. bd->addr, bd->addr + bd->size_nolit, bd->addr + bd->size,
  2687. tcache_id, bd - block_tables[tcache_id]);
  2688. if (bd->addr == 0 || bd->entry_count == 0) {
  2689. dbg(1, " killing dead block!? %08x", bd->addr);
  2690. return;
  2691. }
  2692. // remove from inval_lookup
  2693. addr = bd->addr & ~(INVAL_PAGE_SIZE - 1);
  2694. end_addr = bd->addr + bd->size;
  2695. for (; addr < end_addr; addr += INVAL_PAGE_SIZE) {
  2696. i = (addr & ram_mask) / INVAL_PAGE_SIZE;
  2697. rm_from_block_list(&inval_lookup[tcache_id][i], bd);
  2698. }
  2699. tmp = tcache_ptr;
  2700. bl_unresolved = unresolved_links[tcache_id];
  2701. // remove from hash table, make incoming links unresolved
  2702. // XXX: maybe patch branches w/flush instead?
  2703. for (i = 0; i < bd->entry_count; i++) {
  2704. rm_from_hashlist(&bd->entryp[i], tcache_id);
  2705. // since we never reuse tcache space of dead blocks,
  2706. // insert jump to dispatcher for blocks that are linked to this
  2707. tcache_ptr = bd->entryp[i].tcache_ptr;
  2708. emit_move_r_imm32(SHR_PC, bd->entryp[i].pc);
  2709. rcache_flush();
  2710. emith_jump(sh2_drc_dispatcher);
  2711. host_instructions_updated(bd->entryp[i].tcache_ptr, tcache_ptr);
  2712. for (bl = bd->entryp[i].links; bl != NULL; ) {
  2713. bl_next = bl->next;
  2714. bl->next = bl_unresolved;
  2715. bl_unresolved = bl;
  2716. bl = bl_next;
  2717. }
  2718. }
  2719. tcache_ptr = tmp;
  2720. unresolved_links[tcache_id] = bl_unresolved;
  2721. bd->addr = bd->size = bd->size_nolit = 0;
  2722. bd->entry_count = 0;
  2723. }
  2724. static void sh2_smc_rm_block(u32 a, u16 *drc_ram_blk, int tcache_id, u32 shift, u32 mask)
  2725. {
  2726. struct block_list **blist = NULL, *entry;
  2727. u32 from = ~0, to = 0, end_addr, taddr, i;
  2728. struct block_desc *block;
  2729. blist = &inval_lookup[tcache_id][(a & mask) / INVAL_PAGE_SIZE];
  2730. entry = *blist;
  2731. while (entry != NULL) {
  2732. block = entry->block;
  2733. end_addr = block->addr + block->size;
  2734. if (block->addr <= a && a < end_addr) {
  2735. // get addr range that includes all removed blocks
  2736. if (from > block->addr)
  2737. from = block->addr;
  2738. if (to < end_addr)
  2739. to = end_addr;
  2740. sh2_smc_rm_block_entry(block, tcache_id, mask);
  2741. if (a >= block->addr + block->size_nolit)
  2742. literal_disabled_frames = 3;
  2743. // entry lost, restart search
  2744. entry = *blist;
  2745. continue;
  2746. }
  2747. entry = entry->next;
  2748. }
  2749. if (from >= to)
  2750. return;
  2751. // update range around a to match latest state
  2752. from &= ~(INVAL_PAGE_SIZE - 1);
  2753. to |= (INVAL_PAGE_SIZE - 1);
  2754. for (taddr = from; taddr < to; taddr += INVAL_PAGE_SIZE) {
  2755. i = (taddr & mask) / INVAL_PAGE_SIZE;
  2756. entry = inval_lookup[tcache_id][i];
  2757. for (; entry != NULL; entry = entry->next) {
  2758. block = entry->block;
  2759. if (block->addr > a) {
  2760. if (to > block->addr)
  2761. to = block->addr;
  2762. }
  2763. else {
  2764. end_addr = block->addr + block->size;
  2765. if (from < end_addr)
  2766. from = end_addr;
  2767. }
  2768. }
  2769. }
  2770. // clear code marks
  2771. if (from < to) {
  2772. u16 *p = drc_ram_blk + ((from & mask) >> shift);
  2773. memset(p, 0, (to - from) >> (shift - 1));
  2774. }
  2775. }
  2776. void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
  2777. {
  2778. dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
  2779. sh2_smc_rm_block(a, Pico32xMem->drcblk_ram, 0, SH2_DRCBLK_RAM_SHIFT, 0x3ffff);
  2780. }
  2781. void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
  2782. {
  2783. dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
  2784. sh2_smc_rm_block(a, Pico32xMem->drcblk_da[cpuid],
  2785. 1 + cpuid, SH2_DRCBLK_DA_SHIFT, 0xfff);
  2786. }
  2787. int sh2_execute_drc(SH2 *sh2c, int cycles)
  2788. {
  2789. int ret_cycles;
  2790. // cycles are kept in SHR_SR unused bits (upper 20)
  2791. // bit11 contains T saved for delay slot
  2792. // others are usual SH2 flags
  2793. sh2c->sr &= 0x3f3;
  2794. sh2c->sr |= cycles << 12;
  2795. sh2_drc_entry(sh2c);
  2796. // TODO: irq cycles
  2797. ret_cycles = (signed int)sh2c->sr >> 12;
  2798. if (ret_cycles > 0)
  2799. dbg(1, "warning: drc returned with cycles: %d", ret_cycles);
  2800. sh2c->sr &= 0x3f3;
  2801. return ret_cycles;
  2802. }
  2803. #if (DRC_DEBUG & 2)
  2804. void block_stats(void)
  2805. {
  2806. int c, b, i, total = 0;
  2807. printf("block stats:\n");
  2808. for (b = 0; b < ARRAY_SIZE(block_tables); b++)
  2809. for (i = 0; i < block_counts[b]; i++)
  2810. if (block_tables[b][i].addr != 0)
  2811. total += block_tables[b][i].refcount;
  2812. for (c = 0; c < 10; c++) {
  2813. struct block_desc *blk, *maxb = NULL;
  2814. int max = 0;
  2815. for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
  2816. for (i = 0; i < block_counts[b]; i++) {
  2817. blk = &block_tables[b][i];
  2818. if (blk->addr != 0 && blk->refcount > max) {
  2819. max = blk->refcount;
  2820. maxb = blk;
  2821. }
  2822. }
  2823. }
  2824. if (maxb == NULL)
  2825. break;
  2826. printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
  2827. (double)maxb->refcount / total * 100.0);
  2828. maxb->refcount = 0;
  2829. }
  2830. for (b = 0; b < ARRAY_SIZE(block_tables); b++)
  2831. for (i = 0; i < block_counts[b]; i++)
  2832. block_tables[b][i].refcount = 0;
  2833. }
  2834. #else
  2835. #define block_stats()
  2836. #endif
  2837. void sh2_drc_flush_all(void)
  2838. {
  2839. block_stats();
  2840. flush_tcache(0);
  2841. flush_tcache(1);
  2842. flush_tcache(2);
  2843. }
  2844. void sh2_drc_mem_setup(SH2 *sh2)
  2845. {
  2846. // fill the convenience pointers
  2847. sh2->p_bios = sh2->is_slave ? Pico32xMem->sh2_rom_s.w : Pico32xMem->sh2_rom_m.w;
  2848. sh2->p_da = sh2->data_array;
  2849. sh2->p_sdram = Pico32xMem->sdram;
  2850. sh2->p_rom = Pico.rom;
  2851. }
  2852. void sh2_drc_frame(void)
  2853. {
  2854. if (literal_disabled_frames > 0)
  2855. literal_disabled_frames--;
  2856. }
  2857. int sh2_drc_init(SH2 *sh2)
  2858. {
  2859. int i;
  2860. if (block_tables[0] == NULL)
  2861. {
  2862. for (i = 0; i < TCACHE_BUFFERS; i++) {
  2863. block_tables[i] = calloc(block_max_counts[i], sizeof(*block_tables[0]));
  2864. if (block_tables[i] == NULL)
  2865. goto fail;
  2866. // max 2 block links (exits) per block
  2867. block_link_pool[i] = calloc(block_link_pool_max_counts[i],
  2868. sizeof(*block_link_pool[0]));
  2869. if (block_link_pool[i] == NULL)
  2870. goto fail;
  2871. inval_lookup[i] = calloc(ram_sizes[i] / INVAL_PAGE_SIZE,
  2872. sizeof(inval_lookup[0]));
  2873. if (inval_lookup[i] == NULL)
  2874. goto fail;
  2875. hash_tables[i] = calloc(hash_table_sizes[i], sizeof(*hash_tables[0]));
  2876. if (hash_tables[i] == NULL)
  2877. goto fail;
  2878. }
  2879. memset(block_counts, 0, sizeof(block_counts));
  2880. memset(block_link_pool_counts, 0, sizeof(block_link_pool_counts));
  2881. drc_cmn_init();
  2882. tcache_ptr = tcache;
  2883. sh2_generate_utils();
  2884. host_instructions_updated(tcache, tcache_ptr);
  2885. tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
  2886. for (i = 1; i < ARRAY_SIZE(tcache_bases); i++)
  2887. tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
  2888. #if (DRC_DEBUG & 4)
  2889. for (i = 0; i < ARRAY_SIZE(block_tables); i++)
  2890. tcache_dsm_ptrs[i] = tcache_bases[i];
  2891. // disasm the utils
  2892. tcache_dsm_ptrs[0] = tcache;
  2893. do_host_disasm(0);
  2894. #endif
  2895. #if (DRC_DEBUG & 1)
  2896. hash_collisions = 0;
  2897. #endif
  2898. }
  2899. return 0;
  2900. fail:
  2901. sh2_drc_finish(sh2);
  2902. return -1;
  2903. }
  2904. void sh2_drc_finish(SH2 *sh2)
  2905. {
  2906. int i;
  2907. if (block_tables[0] == NULL)
  2908. return;
  2909. sh2_drc_flush_all();
  2910. for (i = 0; i < TCACHE_BUFFERS; i++) {
  2911. #if (DRC_DEBUG & 4)
  2912. printf("~~~ tcache %d\n", i);
  2913. tcache_dsm_ptrs[i] = tcache_bases[i];
  2914. tcache_ptr = tcache_ptrs[i];
  2915. do_host_disasm(i);
  2916. #endif
  2917. if (block_tables[i] != NULL)
  2918. free(block_tables[i]);
  2919. block_tables[i] = NULL;
  2920. if (block_link_pool[i] == NULL)
  2921. free(block_link_pool[i]);
  2922. block_link_pool[i] = NULL;
  2923. if (inval_lookup[i] == NULL)
  2924. free(inval_lookup[i]);
  2925. inval_lookup[i] = NULL;
  2926. if (hash_tables[i] != NULL) {
  2927. free(hash_tables[i]);
  2928. hash_tables[i] = NULL;
  2929. }
  2930. }
  2931. drc_cmn_cleanup();
  2932. }
  2933. #endif /* DRC_SH2 */
  2934. static void *dr_get_pc_base(u32 pc, int is_slave)
  2935. {
  2936. void *ret = NULL;
  2937. u32 mask = 0;
  2938. if ((pc & ~0x7ff) == 0) {
  2939. // BIOS
  2940. ret = is_slave ? Pico32xMem->sh2_rom_s.w : Pico32xMem->sh2_rom_m.w;
  2941. mask = 0x7ff;
  2942. }
  2943. else if ((pc & 0xfffff000) == 0xc0000000) {
  2944. // data array
  2945. ret = sh2s[is_slave].data_array;
  2946. mask = 0xfff;
  2947. }
  2948. else if ((pc & 0xc6000000) == 0x06000000) {
  2949. // SDRAM
  2950. ret = Pico32xMem->sdram;
  2951. mask = 0x03ffff;
  2952. }
  2953. else if ((pc & 0xc6000000) == 0x02000000) {
  2954. // ROM
  2955. if ((pc & 0x3fffff) < Pico.romsize)
  2956. ret = Pico.rom;
  2957. mask = 0x3fffff;
  2958. }
  2959. if (ret == NULL)
  2960. return (void *)-1; // NULL is valid value
  2961. return (char *)ret - (pc & ~mask);
  2962. }
  2963. void scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc_out,
  2964. u32 *end_literals_out)
  2965. {
  2966. u16 *dr_pc_base;
  2967. u32 pc, op, tmp;
  2968. u32 end_pc, end_literals = 0;
  2969. u32 lowest_mova = 0;
  2970. struct op_data *opd;
  2971. int next_is_delay = 0;
  2972. int end_block = 0;
  2973. int i, i_end;
  2974. memset(op_flags, 0, BLOCK_INSN_LIMIT);
  2975. dr_pc_base = dr_get_pc_base(base_pc, is_slave);
  2976. // 1st pass: disassemble
  2977. for (i = 0, pc = base_pc; ; i++, pc += 2) {
  2978. // we need an ops[] entry after the last one initialized,
  2979. // so do it before end_block checks
  2980. opd = &ops[i];
  2981. opd->op = OP_UNHANDLED;
  2982. opd->rm = -1;
  2983. opd->source = opd->dest = 0;
  2984. opd->cycles = 1;
  2985. opd->imm = 0;
  2986. if (next_is_delay) {
  2987. op_flags[i] |= OF_DELAY_OP;
  2988. next_is_delay = 0;
  2989. }
  2990. else if (end_block || i >= BLOCK_INSN_LIMIT - 2)
  2991. break;
  2992. op = FETCH_OP(pc);
  2993. switch ((op & 0xf000) >> 12)
  2994. {
  2995. /////////////////////////////////////////////
  2996. case 0x00:
  2997. switch (op & 0x0f)
  2998. {
  2999. case 0x02:
  3000. switch (GET_Fx())
  3001. {
  3002. case 0: // STC SR,Rn 0000nnnn00000010
  3003. tmp = SHR_SR;
  3004. break;
  3005. case 1: // STC GBR,Rn 0000nnnn00010010
  3006. tmp = SHR_GBR;
  3007. break;
  3008. case 2: // STC VBR,Rn 0000nnnn00100010
  3009. tmp = SHR_VBR;
  3010. break;
  3011. default:
  3012. goto undefined;
  3013. }
  3014. opd->op = OP_MOVE;
  3015. opd->source = BITMASK1(tmp);
  3016. opd->dest = BITMASK1(GET_Rn());
  3017. break;
  3018. case 0x03:
  3019. CHECK_UNHANDLED_BITS(0xd0, undefined);
  3020. // BRAF Rm 0000mmmm00100011
  3021. // BSRF Rm 0000mmmm00000011
  3022. opd->op = OP_BRANCH_RF;
  3023. opd->rm = GET_Rn();
  3024. opd->source = BITMASK1(opd->rm);
  3025. opd->dest = BITMASK1(SHR_PC);
  3026. if (!(op & 0x20))
  3027. opd->dest |= BITMASK1(SHR_PR);
  3028. opd->cycles = 2;
  3029. next_is_delay = 1;
  3030. end_block = 1;
  3031. break;
  3032. case 0x04: // MOV.B Rm,@(R0,Rn) 0000nnnnmmmm0100
  3033. case 0x05: // MOV.W Rm,@(R0,Rn) 0000nnnnmmmm0101
  3034. case 0x06: // MOV.L Rm,@(R0,Rn) 0000nnnnmmmm0110
  3035. opd->source = BITMASK3(GET_Rm(), SHR_R0, GET_Rn());
  3036. break;
  3037. case 0x07:
  3038. // MUL.L Rm,Rn 0000nnnnmmmm0111
  3039. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3040. opd->dest = BITMASK1(SHR_MACL);
  3041. opd->cycles = 2;
  3042. break;
  3043. case 0x08:
  3044. CHECK_UNHANDLED_BITS(0xf00, undefined);
  3045. switch (GET_Fx())
  3046. {
  3047. case 0: // CLRT 0000000000001000
  3048. opd->op = OP_SETCLRT;
  3049. opd->dest = BITMASK1(SHR_T);
  3050. opd->imm = 0;
  3051. break;
  3052. case 1: // SETT 0000000000011000
  3053. opd->op = OP_SETCLRT;
  3054. opd->dest = BITMASK1(SHR_T);
  3055. opd->imm = 1;
  3056. break;
  3057. case 2: // CLRMAC 0000000000101000
  3058. opd->dest = BITMASK3(SHR_T, SHR_MACL, SHR_MACH);
  3059. break;
  3060. default:
  3061. goto undefined;
  3062. }
  3063. break;
  3064. case 0x09:
  3065. switch (GET_Fx())
  3066. {
  3067. case 0: // NOP 0000000000001001
  3068. CHECK_UNHANDLED_BITS(0xf00, undefined);
  3069. break;
  3070. case 1: // DIV0U 0000000000011001
  3071. CHECK_UNHANDLED_BITS(0xf00, undefined);
  3072. opd->dest = BITMASK2(SHR_SR, SHR_T);
  3073. break;
  3074. case 2: // MOVT Rn 0000nnnn00101001
  3075. opd->source = BITMASK1(SHR_T);
  3076. opd->dest = BITMASK1(GET_Rn());
  3077. break;
  3078. default:
  3079. goto undefined;
  3080. }
  3081. break;
  3082. case 0x0a:
  3083. switch (GET_Fx())
  3084. {
  3085. case 0: // STS MACH,Rn 0000nnnn00001010
  3086. tmp = SHR_MACH;
  3087. break;
  3088. case 1: // STS MACL,Rn 0000nnnn00011010
  3089. tmp = SHR_MACL;
  3090. break;
  3091. case 2: // STS PR,Rn 0000nnnn00101010
  3092. tmp = SHR_PR;
  3093. break;
  3094. default:
  3095. goto undefined;
  3096. }
  3097. opd->op = OP_MOVE;
  3098. opd->source = BITMASK1(tmp);
  3099. opd->dest = BITMASK1(GET_Rn());
  3100. break;
  3101. case 0x0b:
  3102. CHECK_UNHANDLED_BITS(0xf00, undefined);
  3103. switch (GET_Fx())
  3104. {
  3105. case 0: // RTS 0000000000001011
  3106. opd->op = OP_BRANCH_R;
  3107. opd->rm = SHR_PR;
  3108. opd->source = BITMASK1(opd->rm);
  3109. opd->dest = BITMASK1(SHR_PC);
  3110. opd->cycles = 2;
  3111. next_is_delay = 1;
  3112. end_block = 1;
  3113. break;
  3114. case 1: // SLEEP 0000000000011011
  3115. opd->op = OP_SLEEP;
  3116. end_block = 1;
  3117. break;
  3118. case 2: // RTE 0000000000101011
  3119. opd->op = OP_RTE;
  3120. opd->source = BITMASK1(SHR_SP);
  3121. opd->dest = BITMASK2(SHR_SR, SHR_PC);
  3122. opd->cycles = 4;
  3123. next_is_delay = 1;
  3124. end_block = 1;
  3125. break;
  3126. default:
  3127. goto undefined;
  3128. }
  3129. break;
  3130. case 0x0c: // MOV.B @(R0,Rm),Rn 0000nnnnmmmm1100
  3131. case 0x0d: // MOV.W @(R0,Rm),Rn 0000nnnnmmmm1101
  3132. case 0x0e: // MOV.L @(R0,Rm),Rn 0000nnnnmmmm1110
  3133. opd->source = BITMASK2(GET_Rm(), SHR_R0);
  3134. opd->dest = BITMASK1(GET_Rn());
  3135. break;
  3136. case 0x0f: // MAC.L @Rm+,@Rn+ 0000nnnnmmmm1111
  3137. opd->source = BITMASK5(GET_Rm(), GET_Rn(), SHR_SR, SHR_MACL, SHR_MACH);
  3138. opd->dest = BITMASK4(GET_Rm(), GET_Rn(), SHR_MACL, SHR_MACH);
  3139. opd->cycles = 3;
  3140. break;
  3141. default:
  3142. goto undefined;
  3143. }
  3144. break;
  3145. /////////////////////////////////////////////
  3146. case 0x01:
  3147. // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
  3148. opd->source = BITMASK1(GET_Rm());
  3149. opd->source = BITMASK1(GET_Rn());
  3150. opd->imm = (op & 0x0f) * 4;
  3151. break;
  3152. /////////////////////////////////////////////
  3153. case 0x02:
  3154. switch (op & 0x0f)
  3155. {
  3156. case 0x00: // MOV.B Rm,@Rn 0010nnnnmmmm0000
  3157. case 0x01: // MOV.W Rm,@Rn 0010nnnnmmmm0001
  3158. case 0x02: // MOV.L Rm,@Rn 0010nnnnmmmm0010
  3159. opd->source = BITMASK1(GET_Rm());
  3160. opd->source = BITMASK1(GET_Rn());
  3161. break;
  3162. case 0x04: // MOV.B Rm,@-Rn 0010nnnnmmmm0100
  3163. case 0x05: // MOV.W Rm,@-Rn 0010nnnnmmmm0101
  3164. case 0x06: // MOV.L Rm,@-Rn 0010nnnnmmmm0110
  3165. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3166. opd->dest = BITMASK1(GET_Rn());
  3167. break;
  3168. case 0x07: // DIV0S Rm,Rn 0010nnnnmmmm0111
  3169. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3170. opd->dest = BITMASK1(SHR_SR);
  3171. break;
  3172. case 0x08: // TST Rm,Rn 0010nnnnmmmm1000
  3173. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3174. opd->dest = BITMASK1(SHR_T);
  3175. break;
  3176. case 0x09: // AND Rm,Rn 0010nnnnmmmm1001
  3177. case 0x0a: // XOR Rm,Rn 0010nnnnmmmm1010
  3178. case 0x0b: // OR Rm,Rn 0010nnnnmmmm1011
  3179. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3180. opd->dest = BITMASK1(GET_Rn());
  3181. break;
  3182. case 0x0c: // CMP/STR Rm,Rn 0010nnnnmmmm1100
  3183. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3184. opd->dest = BITMASK1(SHR_T);
  3185. break;
  3186. case 0x0d: // XTRCT Rm,Rn 0010nnnnmmmm1101
  3187. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3188. opd->dest = BITMASK1(GET_Rn());
  3189. break;
  3190. case 0x0e: // MULU.W Rm,Rn 0010nnnnmmmm1110
  3191. case 0x0f: // MULS.W Rm,Rn 0010nnnnmmmm1111
  3192. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3193. opd->dest = BITMASK1(SHR_MACL);
  3194. break;
  3195. default:
  3196. goto undefined;
  3197. }
  3198. break;
  3199. /////////////////////////////////////////////
  3200. case 0x03:
  3201. switch (op & 0x0f)
  3202. {
  3203. case 0x00: // CMP/EQ Rm,Rn 0011nnnnmmmm0000
  3204. case 0x02: // CMP/HS Rm,Rn 0011nnnnmmmm0010
  3205. case 0x03: // CMP/GE Rm,Rn 0011nnnnmmmm0011
  3206. case 0x06: // CMP/HI Rm,Rn 0011nnnnmmmm0110
  3207. case 0x07: // CMP/GT Rm,Rn 0011nnnnmmmm0111
  3208. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3209. opd->dest = BITMASK1(SHR_T);
  3210. break;
  3211. case 0x04: // DIV1 Rm,Rn 0011nnnnmmmm0100
  3212. opd->source = BITMASK3(GET_Rm(), GET_Rn(), SHR_SR);
  3213. opd->dest = BITMASK2(GET_Rn(), SHR_SR);
  3214. break;
  3215. case 0x05: // DMULU.L Rm,Rn 0011nnnnmmmm0101
  3216. case 0x0d: // DMULS.L Rm,Rn 0011nnnnmmmm1101
  3217. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3218. opd->dest = BITMASK2(SHR_MACL, SHR_MACH);
  3219. opd->cycles = 2;
  3220. break;
  3221. case 0x08: // SUB Rm,Rn 0011nnnnmmmm1000
  3222. case 0x0c: // ADD Rm,Rn 0011nnnnmmmm1100
  3223. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3224. opd->dest = BITMASK1(GET_Rn());
  3225. break;
  3226. case 0x0a: // SUBC Rm,Rn 0011nnnnmmmm1010
  3227. case 0x0e: // ADDC Rm,Rn 0011nnnnmmmm1110
  3228. opd->source = BITMASK3(GET_Rm(), GET_Rn(), SHR_T);
  3229. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3230. break;
  3231. case 0x0b: // SUBV Rm,Rn 0011nnnnmmmm1011
  3232. case 0x0f: // ADDV Rm,Rn 0011nnnnmmmm1111
  3233. opd->source = BITMASK2(GET_Rm(), GET_Rn());
  3234. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3235. break;
  3236. default:
  3237. goto undefined;
  3238. }
  3239. break;
  3240. /////////////////////////////////////////////
  3241. case 0x04:
  3242. switch (op & 0x0f)
  3243. {
  3244. case 0x00:
  3245. switch (GET_Fx())
  3246. {
  3247. case 0: // SHLL Rn 0100nnnn00000000
  3248. case 2: // SHAL Rn 0100nnnn00100000
  3249. opd->source = BITMASK1(GET_Rn());
  3250. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3251. break;
  3252. case 1: // DT Rn 0100nnnn00010000
  3253. opd->source = BITMASK1(GET_Rn());
  3254. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3255. break;
  3256. default:
  3257. goto undefined;
  3258. }
  3259. break;
  3260. case 0x01:
  3261. switch (GET_Fx())
  3262. {
  3263. case 0: // SHLR Rn 0100nnnn00000001
  3264. case 2: // SHAR Rn 0100nnnn00100001
  3265. opd->source = BITMASK1(GET_Rn());
  3266. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3267. break;
  3268. case 1: // CMP/PZ Rn 0100nnnn00010001
  3269. opd->source = BITMASK1(GET_Rn());
  3270. opd->dest = BITMASK1(SHR_T);
  3271. break;
  3272. default:
  3273. goto undefined;
  3274. }
  3275. break;
  3276. case 0x02:
  3277. case 0x03:
  3278. switch (op & 0x3f)
  3279. {
  3280. case 0x02: // STS.L MACH,@-Rn 0100nnnn00000010
  3281. tmp = SHR_MACH;
  3282. break;
  3283. case 0x12: // STS.L MACL,@-Rn 0100nnnn00010010
  3284. tmp = SHR_MACL;
  3285. break;
  3286. case 0x22: // STS.L PR,@-Rn 0100nnnn00100010
  3287. tmp = SHR_PR;
  3288. break;
  3289. case 0x03: // STC.L SR,@-Rn 0100nnnn00000011
  3290. tmp = SHR_SR;
  3291. opd->cycles = 2;
  3292. break;
  3293. case 0x13: // STC.L GBR,@-Rn 0100nnnn00010011
  3294. tmp = SHR_GBR;
  3295. opd->cycles = 2;
  3296. break;
  3297. case 0x23: // STC.L VBR,@-Rn 0100nnnn00100011
  3298. tmp = SHR_VBR;
  3299. opd->cycles = 2;
  3300. break;
  3301. default:
  3302. goto undefined;
  3303. }
  3304. opd->source = BITMASK2(GET_Rn(), tmp);
  3305. opd->dest = BITMASK1(GET_Rn());
  3306. break;
  3307. case 0x04:
  3308. case 0x05:
  3309. switch (op & 0x3f)
  3310. {
  3311. case 0x04: // ROTL Rn 0100nnnn00000100
  3312. case 0x05: // ROTR Rn 0100nnnn00000101
  3313. opd->source = BITMASK1(GET_Rn());
  3314. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3315. break;
  3316. case 0x24: // ROTCL Rn 0100nnnn00100100
  3317. case 0x25: // ROTCR Rn 0100nnnn00100101
  3318. opd->source = BITMASK2(GET_Rn(), SHR_T);
  3319. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3320. break;
  3321. case 0x15: // CMP/PL Rn 0100nnnn00010101
  3322. opd->source = BITMASK1(GET_Rn());
  3323. opd->dest = BITMASK1(SHR_T);
  3324. break;
  3325. default:
  3326. goto undefined;
  3327. }
  3328. break;
  3329. case 0x06:
  3330. case 0x07:
  3331. switch (op & 0x3f)
  3332. {
  3333. case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
  3334. tmp = SHR_MACH;
  3335. break;
  3336. case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
  3337. tmp = SHR_MACL;
  3338. break;
  3339. case 0x26: // LDS.L @Rm+,PR 0100mmmm00100110
  3340. tmp = SHR_PR;
  3341. break;
  3342. case 0x07: // LDC.L @Rm+,SR 0100mmmm00000111
  3343. tmp = SHR_SR;
  3344. opd->cycles = 3;
  3345. break;
  3346. case 0x17: // LDC.L @Rm+,GBR 0100mmmm00010111
  3347. tmp = SHR_GBR;
  3348. opd->cycles = 3;
  3349. break;
  3350. case 0x27: // LDC.L @Rm+,VBR 0100mmmm00100111
  3351. tmp = SHR_VBR;
  3352. opd->cycles = 3;
  3353. break;
  3354. default:
  3355. goto undefined;
  3356. }
  3357. opd->source = BITMASK1(GET_Rn());
  3358. opd->dest = BITMASK2(GET_Rn(), tmp);
  3359. break;
  3360. case 0x08:
  3361. case 0x09:
  3362. switch (GET_Fx())
  3363. {
  3364. case 0:
  3365. // SHLL2 Rn 0100nnnn00001000
  3366. // SHLR2 Rn 0100nnnn00001001
  3367. break;
  3368. case 1:
  3369. // SHLL8 Rn 0100nnnn00011000
  3370. // SHLR8 Rn 0100nnnn00011001
  3371. break;
  3372. case 2:
  3373. // SHLL16 Rn 0100nnnn00101000
  3374. // SHLR16 Rn 0100nnnn00101001
  3375. break;
  3376. default:
  3377. goto undefined;
  3378. }
  3379. opd->source = BITMASK1(GET_Rn());
  3380. opd->dest = BITMASK1(GET_Rn());
  3381. break;
  3382. case 0x0a:
  3383. switch (GET_Fx())
  3384. {
  3385. case 0: // LDS Rm,MACH 0100mmmm00001010
  3386. tmp = SHR_MACH;
  3387. break;
  3388. case 1: // LDS Rm,MACL 0100mmmm00011010
  3389. tmp = SHR_MACL;
  3390. break;
  3391. case 2: // LDS Rm,PR 0100mmmm00101010
  3392. tmp = SHR_PR;
  3393. break;
  3394. default:
  3395. goto undefined;
  3396. }
  3397. opd->op = OP_MOVE;
  3398. opd->source = BITMASK1(GET_Rn());
  3399. opd->dest = BITMASK1(tmp);
  3400. break;
  3401. case 0x0b:
  3402. switch (GET_Fx())
  3403. {
  3404. case 0: // JSR @Rm 0100mmmm00001011
  3405. opd->dest = BITMASK1(SHR_PR);
  3406. case 2: // JMP @Rm 0100mmmm00101011
  3407. opd->op = OP_BRANCH_R;
  3408. opd->rm = GET_Rn();
  3409. opd->source = BITMASK1(opd->rm);
  3410. opd->dest |= BITMASK1(SHR_PC);
  3411. opd->cycles = 2;
  3412. next_is_delay = 1;
  3413. end_block = 1;
  3414. break;
  3415. case 1: // TAS.B @Rn 0100nnnn00011011
  3416. opd->source = BITMASK1(GET_Rn());
  3417. opd->dest = BITMASK1(SHR_T);
  3418. opd->cycles = 4;
  3419. break;
  3420. default:
  3421. goto undefined;
  3422. }
  3423. break;
  3424. case 0x0e:
  3425. switch (GET_Fx())
  3426. {
  3427. case 0: // LDC Rm,SR 0100mmmm00001110
  3428. tmp = SHR_SR;
  3429. break;
  3430. case 1: // LDC Rm,GBR 0100mmmm00011110
  3431. tmp = SHR_GBR;
  3432. break;
  3433. case 2: // LDC Rm,VBR 0100mmmm00101110
  3434. tmp = SHR_VBR;
  3435. break;
  3436. default:
  3437. goto undefined;
  3438. }
  3439. opd->op = OP_MOVE;
  3440. opd->source = BITMASK1(GET_Rn());
  3441. opd->dest = BITMASK1(tmp);
  3442. break;
  3443. case 0x0f:
  3444. // MAC.W @Rm+,@Rn+ 0100nnnnmmmm1111
  3445. opd->source = BITMASK5(GET_Rm(), GET_Rn(), SHR_SR, SHR_MACL, SHR_MACH);
  3446. opd->dest = BITMASK4(GET_Rm(), GET_Rn(), SHR_MACL, SHR_MACH);
  3447. opd->cycles = 3;
  3448. break;
  3449. default:
  3450. goto undefined;
  3451. }
  3452. break;
  3453. /////////////////////////////////////////////
  3454. case 0x05:
  3455. // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
  3456. opd->source = BITMASK1(GET_Rm());
  3457. opd->dest = BITMASK1(GET_Rn());
  3458. opd->imm = (op & 0x0f) * 4;
  3459. break;
  3460. /////////////////////////////////////////////
  3461. case 0x06:
  3462. switch (op & 0x0f)
  3463. {
  3464. case 0x04: // MOV.B @Rm+,Rn 0110nnnnmmmm0100
  3465. case 0x05: // MOV.W @Rm+,Rn 0110nnnnmmmm0101
  3466. case 0x06: // MOV.L @Rm+,Rn 0110nnnnmmmm0110
  3467. opd->dest = BITMASK1(GET_Rm());
  3468. case 0x00: // MOV.B @Rm,Rn 0110nnnnmmmm0000
  3469. case 0x01: // MOV.W @Rm,Rn 0110nnnnmmmm0001
  3470. case 0x02: // MOV.L @Rm,Rn 0110nnnnmmmm0010
  3471. opd->source = BITMASK1(GET_Rm());
  3472. opd->dest |= BITMASK1(GET_Rn());
  3473. break;
  3474. case 0x0a: // NEGC Rm,Rn 0110nnnnmmmm1010
  3475. opd->source = BITMASK2(GET_Rm(), SHR_T);
  3476. opd->dest = BITMASK2(GET_Rn(), SHR_T);
  3477. break;
  3478. case 0x03: // MOV Rm,Rn 0110nnnnmmmm0011
  3479. opd->op = OP_MOVE;
  3480. goto arith_rmrn;
  3481. case 0x07: // NOT Rm,Rn 0110nnnnmmmm0111
  3482. case 0x08: // SWAP.B Rm,Rn 0110nnnnmmmm1000
  3483. case 0x09: // SWAP.W Rm,Rn 0110nnnnmmmm1001
  3484. case 0x0b: // NEG Rm,Rn 0110nnnnmmmm1011
  3485. case 0x0c: // EXTU.B Rm,Rn 0110nnnnmmmm1100
  3486. case 0x0d: // EXTU.W Rm,Rn 0110nnnnmmmm1101
  3487. case 0x0e: // EXTS.B Rm,Rn 0110nnnnmmmm1110
  3488. case 0x0f: // EXTS.W Rm,Rn 0110nnnnmmmm1111
  3489. arith_rmrn:
  3490. opd->source = BITMASK1(GET_Rm());
  3491. opd->dest = BITMASK1(GET_Rn());
  3492. break;
  3493. }
  3494. break;
  3495. /////////////////////////////////////////////
  3496. case 0x07:
  3497. // ADD #imm,Rn 0111nnnniiiiiiii
  3498. opd->source = opd->dest = BITMASK1(GET_Rn());
  3499. opd->imm = (int)(signed char)op;
  3500. break;
  3501. /////////////////////////////////////////////
  3502. case 0x08:
  3503. switch (op & 0x0f00)
  3504. {
  3505. case 0x0000: // MOV.B R0,@(disp,Rn) 10000000nnnndddd
  3506. opd->source = BITMASK2(GET_Rm(), SHR_R0);
  3507. opd->imm = (op & 0x0f);
  3508. break;
  3509. case 0x0100: // MOV.W R0,@(disp,Rn) 10000001nnnndddd
  3510. opd->source = BITMASK2(GET_Rm(), SHR_R0);
  3511. opd->imm = (op & 0x0f) * 2;
  3512. break;
  3513. case 0x0400: // MOV.B @(disp,Rm),R0 10000100mmmmdddd
  3514. opd->source = BITMASK1(GET_Rm());
  3515. opd->dest = BITMASK1(SHR_R0);
  3516. opd->imm = (op & 0x0f);
  3517. break;
  3518. case 0x0500: // MOV.W @(disp,Rm),R0 10000101mmmmdddd
  3519. opd->source = BITMASK1(GET_Rm());
  3520. opd->dest = BITMASK1(SHR_R0);
  3521. opd->imm = (op & 0x0f) * 2;
  3522. break;
  3523. case 0x0800: // CMP/EQ #imm,R0 10001000iiiiiiii
  3524. opd->source = BITMASK1(SHR_R0);
  3525. opd->dest = BITMASK1(SHR_T);
  3526. opd->imm = (int)(signed char)op;
  3527. break;
  3528. case 0x0d00: // BT/S label 10001101dddddddd
  3529. case 0x0f00: // BF/S label 10001111dddddddd
  3530. next_is_delay = 1;
  3531. // fallthrough
  3532. case 0x0900: // BT label 10001001dddddddd
  3533. case 0x0b00: // BF label 10001011dddddddd
  3534. opd->op = (op & 0x0200) ? OP_BRANCH_CF : OP_BRANCH_CT;
  3535. opd->source = BITMASK1(SHR_T);
  3536. opd->dest = BITMASK1(SHR_PC);
  3537. opd->imm = ((signed int)(op << 24) >> 23);
  3538. opd->imm += pc + 4;
  3539. if (base_pc <= opd->imm && opd->imm < base_pc + BLOCK_INSN_LIMIT * 2)
  3540. op_flags[(opd->imm - base_pc) / 2] |= OF_BTARGET;
  3541. break;
  3542. default:
  3543. goto undefined;
  3544. }
  3545. break;
  3546. /////////////////////////////////////////////
  3547. case 0x09:
  3548. // MOV.W @(disp,PC),Rn 1001nnnndddddddd
  3549. opd->op = OP_LOAD_POOL;
  3550. tmp = pc + 2;
  3551. if (op_flags[i] & OF_DELAY_OP) {
  3552. if (ops[i-1].op == OP_BRANCH)
  3553. tmp = ops[i-1].imm;
  3554. else
  3555. tmp = 0;
  3556. }
  3557. opd->source = BITMASK1(SHR_PC);
  3558. opd->dest = BITMASK1(GET_Rn());
  3559. if (tmp)
  3560. opd->imm = tmp + 2 + (op & 0xff) * 2;
  3561. opd->size = 1;
  3562. break;
  3563. /////////////////////////////////////////////
  3564. case 0x0b:
  3565. // BSR label 1011dddddddddddd
  3566. opd->dest = BITMASK1(SHR_PR);
  3567. case 0x0a:
  3568. // BRA label 1010dddddddddddd
  3569. opd->op = OP_BRANCH;
  3570. opd->dest |= BITMASK1(SHR_PC);
  3571. opd->imm = ((signed int)(op << 20) >> 19);
  3572. opd->imm += pc + 4;
  3573. opd->cycles = 2;
  3574. next_is_delay = 1;
  3575. end_block = 1;
  3576. if (base_pc <= opd->imm && opd->imm < base_pc + BLOCK_INSN_LIMIT * 2)
  3577. op_flags[(opd->imm - base_pc) / 2] |= OF_BTARGET;
  3578. break;
  3579. /////////////////////////////////////////////
  3580. case 0x0c:
  3581. switch (op & 0x0f00)
  3582. {
  3583. case 0x0000: // MOV.B R0,@(disp,GBR) 11000000dddddddd
  3584. case 0x0100: // MOV.W R0,@(disp,GBR) 11000001dddddddd
  3585. case 0x0200: // MOV.L R0,@(disp,GBR) 11000010dddddddd
  3586. opd->source = BITMASK2(SHR_GBR, SHR_R0);
  3587. opd->size = (op & 0x300) >> 8;
  3588. opd->imm = (op & 0xff) << opd->size;
  3589. break;
  3590. case 0x0400: // MOV.B @(disp,GBR),R0 11000100dddddddd
  3591. case 0x0500: // MOV.W @(disp,GBR),R0 11000101dddddddd
  3592. case 0x0600: // MOV.L @(disp,GBR),R0 11000110dddddddd
  3593. opd->source = BITMASK1(SHR_GBR);
  3594. opd->dest = BITMASK1(SHR_R0);
  3595. opd->size = (op & 0x300) >> 8;
  3596. opd->imm = (op & 0xff) << opd->size;
  3597. break;
  3598. case 0x0300: // TRAPA #imm 11000011iiiiiiii
  3599. opd->source = BITMASK2(SHR_PC, SHR_SR);
  3600. opd->dest = BITMASK1(SHR_PC);
  3601. opd->imm = (op & 0xff) * 4;
  3602. opd->cycles = 8;
  3603. end_block = 1; // FIXME
  3604. break;
  3605. case 0x0700: // MOVA @(disp,PC),R0 11000111dddddddd
  3606. opd->op = OP_MOVA;
  3607. tmp = pc + 2;
  3608. if (op_flags[i] & OF_DELAY_OP) {
  3609. if (ops[i-1].op == OP_BRANCH)
  3610. tmp = ops[i-1].imm;
  3611. else
  3612. tmp = 0;
  3613. }
  3614. opd->dest = BITMASK1(SHR_R0);
  3615. if (tmp) {
  3616. opd->imm = (tmp + 2 + (op & 0xff) * 4) & ~3;
  3617. if (opd->imm >= base_pc) {
  3618. if (lowest_mova == 0 || opd->imm < lowest_mova)
  3619. lowest_mova = opd->imm;
  3620. }
  3621. }
  3622. break;
  3623. case 0x0800: // TST #imm,R0 11001000iiiiiiii
  3624. opd->source = BITMASK1(SHR_R0);
  3625. opd->dest = BITMASK1(SHR_T);
  3626. opd->imm = op & 0xff;
  3627. break;
  3628. case 0x0900: // AND #imm,R0 11001001iiiiiiii
  3629. opd->source = opd->dest = BITMASK1(SHR_R0);
  3630. opd->imm = op & 0xff;
  3631. break;
  3632. case 0x0a00: // XOR #imm,R0 11001010iiiiiiii
  3633. opd->source = opd->dest = BITMASK1(SHR_R0);
  3634. opd->imm = op & 0xff;
  3635. break;
  3636. case 0x0b00: // OR #imm,R0 11001011iiiiiiii
  3637. opd->source = opd->dest = BITMASK1(SHR_R0);
  3638. opd->imm = op & 0xff;
  3639. break;
  3640. case 0x0c00: // TST.B #imm,@(R0,GBR) 11001100iiiiiiii
  3641. opd->source = BITMASK2(SHR_GBR, SHR_R0);
  3642. opd->dest = BITMASK1(SHR_T);
  3643. opd->imm = op & 0xff;
  3644. opd->cycles = 3;
  3645. break;
  3646. case 0x0d00: // AND.B #imm,@(R0,GBR) 11001101iiiiiiii
  3647. case 0x0e00: // XOR.B #imm,@(R0,GBR) 11001110iiiiiiii
  3648. case 0x0f00: // OR.B #imm,@(R0,GBR) 11001111iiiiiiii
  3649. opd->source = BITMASK2(SHR_GBR, SHR_R0);
  3650. opd->imm = op & 0xff;
  3651. opd->cycles = 3;
  3652. break;
  3653. default:
  3654. goto undefined;
  3655. }
  3656. break;
  3657. /////////////////////////////////////////////
  3658. case 0x0d:
  3659. // MOV.L @(disp,PC),Rn 1101nnnndddddddd
  3660. opd->op = OP_LOAD_POOL;
  3661. tmp = pc + 2;
  3662. if (op_flags[i] & OF_DELAY_OP) {
  3663. if (ops[i-1].op == OP_BRANCH)
  3664. tmp = ops[i-1].imm;
  3665. else
  3666. tmp = 0;
  3667. }
  3668. opd->source = BITMASK1(SHR_PC);
  3669. opd->dest = BITMASK1(GET_Rn());
  3670. if (tmp)
  3671. opd->imm = (tmp + 2 + (op & 0xff) * 4) & ~3;
  3672. opd->size = 2;
  3673. break;
  3674. /////////////////////////////////////////////
  3675. case 0x0e:
  3676. // MOV #imm,Rn 1110nnnniiiiiiii
  3677. opd->dest = BITMASK1(GET_Rn());
  3678. opd->imm = (u32)(signed int)(signed char)op;
  3679. break;
  3680. default:
  3681. undefined:
  3682. elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
  3683. is_slave ? 's' : 'm', op, pc);
  3684. break;
  3685. }
  3686. }
  3687. i_end = i;
  3688. end_pc = pc;
  3689. // 2nd pass: some analysis
  3690. for (i = 0; i < i_end; i++) {
  3691. opd = &ops[i];
  3692. // propagate T (TODO: DIV0U)
  3693. if ((opd->op == OP_SETCLRT && !opd->imm) || opd->op == OP_BRANCH_CT)
  3694. op_flags[i + 1] |= OF_T_CLEAR;
  3695. else if ((opd->op == OP_SETCLRT && opd->imm) || opd->op == OP_BRANCH_CF)
  3696. op_flags[i + 1] |= OF_T_SET;
  3697. if ((op_flags[i] & OF_BTARGET) || (opd->dest & BITMASK1(SHR_T)))
  3698. op_flags[i] &= ~(OF_T_SET | OF_T_CLEAR);
  3699. else
  3700. op_flags[i + 1] |= op_flags[i] & (OF_T_SET | OF_T_CLEAR);
  3701. if ((opd->op == OP_BRANCH_CT && (op_flags[i] & OF_T_SET))
  3702. || (opd->op == OP_BRANCH_CF && (op_flags[i] & OF_T_CLEAR)))
  3703. {
  3704. opd->op = OP_BRANCH;
  3705. opd->cycles = 3;
  3706. i_end = i + 1;
  3707. if (op_flags[i + 1] & OF_DELAY_OP) {
  3708. opd->cycles = 2;
  3709. i_end++;
  3710. }
  3711. }
  3712. else if (opd->op == OP_LOAD_POOL)
  3713. {
  3714. if (opd->imm < end_pc + MAX_LITERAL_OFFSET) {
  3715. if (end_literals < opd->imm + opd->size * 2)
  3716. end_literals = opd->imm + opd->size * 2;
  3717. }
  3718. }
  3719. }
  3720. end_pc = base_pc + i_end * 2;
  3721. if (end_literals < end_pc)
  3722. end_literals = end_pc;
  3723. // end_literals is used to decide to inline a literal or not
  3724. // XXX: need better detection if this actually is used in write
  3725. if (lowest_mova >= base_pc) {
  3726. if (lowest_mova < end_literals) {
  3727. dbg(1, "mova for %08x, block %08x", lowest_mova, base_pc);
  3728. end_literals = end_pc;
  3729. }
  3730. if (lowest_mova < end_pc) {
  3731. dbg(1, "warning: mova inside of blk for %08x, block %08x",
  3732. lowest_mova, base_pc);
  3733. end_literals = end_pc;
  3734. }
  3735. }
  3736. *end_pc_out = end_pc;
  3737. if (end_literals_out != NULL)
  3738. *end_literals_out = end_literals;
  3739. }
  3740. // vim:shiftwidth=2:ts=2:expandtab