123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541 |
- /*
- * TMS320C67xx code generator for TCC
- *
- * Copyright (c) 2001, 2002 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #ifdef TARGET_DEFS_ONLY
- /* #define ASSEMBLY_LISTING_C67 */
- /* number of available registers */
- #define NB_REGS 24
- /* a register can belong to several classes. The classes must be
- sorted from more general to more precise (see gv2() code which does
- assumptions on it). */
- #define RC_INT 0x0001 /* generic integer register */
- #define RC_FLOAT 0x0002 /* generic float register */
- #define RC_EAX 0x0004
- #define RC_ST0 0x0008
- #define RC_ECX 0x0010
- #define RC_EDX 0x0020
- #define RC_INT_BSIDE 0x00000040 /* generic integer register on b side */
- #define RC_C67_A4 0x00000100
- #define RC_C67_A5 0x00000200
- #define RC_C67_B4 0x00000400
- #define RC_C67_B5 0x00000800
- #define RC_C67_A6 0x00001000
- #define RC_C67_A7 0x00002000
- #define RC_C67_B6 0x00004000
- #define RC_C67_B7 0x00008000
- #define RC_C67_A8 0x00010000
- #define RC_C67_A9 0x00020000
- #define RC_C67_B8 0x00040000
- #define RC_C67_B9 0x00080000
- #define RC_C67_A10 0x00100000
- #define RC_C67_A11 0x00200000
- #define RC_C67_B10 0x00400000
- #define RC_C67_B11 0x00800000
- #define RC_C67_A12 0x01000000
- #define RC_C67_A13 0x02000000
- #define RC_C67_B12 0x04000000
- #define RC_C67_B13 0x08000000
- #define RC_IRET RC_C67_A4 /* function return: integer register */
- #define RC_LRET RC_C67_A5 /* function return: second integer register */
- #define RC_FRET RC_C67_A4 /* function return: float register */
- /* pretty names for the registers */
- enum {
- TREG_EAX = 0, // really A2
- TREG_ECX, // really A3
- TREG_EDX, // really B0
- TREG_ST0, // really B1
- TREG_C67_A4,
- TREG_C67_A5,
- TREG_C67_B4,
- TREG_C67_B5,
- TREG_C67_A6,
- TREG_C67_A7,
- TREG_C67_B6,
- TREG_C67_B7,
- TREG_C67_A8,
- TREG_C67_A9,
- TREG_C67_B8,
- TREG_C67_B9,
- TREG_C67_A10,
- TREG_C67_A11,
- TREG_C67_B10,
- TREG_C67_B11,
- TREG_C67_A12,
- TREG_C67_A13,
- TREG_C67_B12,
- TREG_C67_B13,
- };
- /* return registers for function */
- #define REG_IRET TREG_C67_A4 /* single word int return register */
- #define REG_LRET TREG_C67_A5 /* second word return register (for long long) */
- #define REG_FRET TREG_C67_A4 /* float return register */
- /* defined if function parameters must be evaluated in reverse order */
- /* #define INVERT_FUNC_PARAMS */
- /* defined if structures are passed as pointers. Otherwise structures
- are directly pushed on stack. */
- /* #define FUNC_STRUCT_PARAM_AS_PTR */
- /* pointer size, in bytes */
- #define PTR_SIZE 4
- /* long double size and alignment, in bytes */
- #define LDOUBLE_SIZE 12
- #define LDOUBLE_ALIGN 4
- /* maximum alignment (for aligned attribute support) */
- #define MAX_ALIGN 8
- /******************************************************/
- #else /* ! TARGET_DEFS_ONLY */
- /******************************************************/
- #include "tcc.h"
- ST_DATA const int reg_classes[NB_REGS] = {
- /* eax */ RC_INT | RC_FLOAT | RC_EAX,
- // only allow even regs for floats (allow for doubles)
- /* ecx */ RC_INT | RC_ECX,
- /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
- // only allow even regs for floats (allow for doubles)
- /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
- /* A4 */ RC_C67_A4,
- /* A5 */ RC_C67_A5,
- /* B4 */ RC_C67_B4,
- /* B5 */ RC_C67_B5,
- /* A6 */ RC_C67_A6,
- /* A7 */ RC_C67_A7,
- /* B6 */ RC_C67_B6,
- /* B7 */ RC_C67_B7,
- /* A8 */ RC_C67_A8,
- /* A9 */ RC_C67_A9,
- /* B8 */ RC_C67_B8,
- /* B9 */ RC_C67_B9,
- /* A10 */ RC_C67_A10,
- /* A11 */ RC_C67_A11,
- /* B10 */ RC_C67_B10,
- /* B11 */ RC_C67_B11,
- /* A12 */ RC_C67_A10,
- /* A13 */ RC_C67_A11,
- /* B12 */ RC_C67_B10,
- /* B13 */ RC_C67_B11
- };
- // although tcc thinks it is passing parameters on the stack,
- // the C67 really passes up to the first 10 params in special
- // regs or regs pairs (for 64 bit params). So keep track of
- // the stack offsets so we can translate to the appropriate
- // reg (pair)
- #define NoCallArgsPassedOnStack 10
- int NoOfCurFuncArgs;
- int TranslateStackToReg[NoCallArgsPassedOnStack];
- int ParamLocOnStack[NoCallArgsPassedOnStack];
- int TotalBytesPushedOnStack;
- #ifndef FALSE
- # define FALSE 0
- # define TRUE 1
- #endif
- #undef BOOL
- #define BOOL int
- #define ALWAYS_ASSERT(x) \
- do {\
- if (!(x))\
- tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
- } while (0)
- /******************************************************/
- static unsigned long func_sub_sp_offset;
- static int func_ret_sub;
- static BOOL C67_invert_test;
- static int C67_compare_reg;
- #ifdef ASSEMBLY_LISTING_C67
- FILE *f = NULL;
- #endif
- void C67_g(int c)
- {
- int ind1;
- if (nocode_wanted)
- return;
- #ifdef ASSEMBLY_LISTING_C67
- fprintf(f, " %08X", c);
- #endif
- ind1 = ind + 4;
- if (ind1 > (int) cur_text_section->data_allocated)
- section_realloc(cur_text_section, ind1);
- cur_text_section->data[ind] = c & 0xff;
- cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
- cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
- cur_text_section->data[ind + 3] = (c >> 24) & 0xff;
- ind = ind1;
- }
- /* output a symbol and patch all calls to it */
- void gsym_addr(int t, int a)
- {
- int n, *ptr;
- while (t) {
- ptr = (int *) (cur_text_section->data + t);
- {
- Sym *sym;
- // extract 32 bit address from MVKH/MVKL
- n = ((*ptr >> 7) & 0xffff);
- n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
- // define a label that will be relocated
- sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
- greloc(cur_text_section, sym, t, R_C60LO16);
- greloc(cur_text_section, sym, t + 4, R_C60HI16);
- // clear out where the pointer was
- *ptr &= ~(0xffff << 7);
- *(ptr + 1) &= ~(0xffff << 7);
- }
- t = n;
- }
- }
- void gsym(int t)
- {
- gsym_addr(t, ind);
- }
- // these are regs that tcc doesn't really know about,
- // but assign them unique values so the mapping routines
- // can distinguish them
- #define C67_A0 105
- #define C67_SP 106
- #define C67_B3 107
- #define C67_FP 108
- #define C67_B2 109
- #define C67_CREG_ZERO -1 /* Special code for no condition reg test */
- int ConvertRegToRegClass(int r)
- {
- // only works for A4-B13
- return RC_C67_A4 << (r - TREG_C67_A4);
- }
- // map TCC reg to C67 reg number
- int C67_map_regn(int r)
- {
- if (r == 0) // normal tcc regs
- return 0x2; // A2
- else if (r == 1) // normal tcc regs
- return 3; // A3
- else if (r == 2) // normal tcc regs
- return 0; // B0
- else if (r == 3) // normal tcc regs
- return 1; // B1
- else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
- return (((r & 0xfffffffc) >> 1) | (r & 1)) + 2;
- else if (r == C67_A0)
- return 0; // set to A0 (offset reg)
- else if (r == C67_B2)
- return 2; // set to B2 (offset reg)
- else if (r == C67_B3)
- return 3; // set to B3 (return address reg)
- else if (r == C67_SP)
- return 15; // set to SP (B15) (offset reg)
- else if (r == C67_FP)
- return 15; // set to FP (A15) (offset reg)
- else if (r == C67_CREG_ZERO)
- return 0; // Special code for no condition reg test
- else
- ALWAYS_ASSERT(FALSE);
- return 0;
- }
- // mapping from tcc reg number to
- // C67 register to condition code field
- //
- // valid condition code regs are:
- //
- // tcc reg 2 ->B0 -> 1
- // tcc reg 3 ->B1 -> 2
- // tcc reg 0 -> A2 -> 5
- // tcc reg 1 -> A3 -> X
- // tcc reg B2 -> 3
- int C67_map_regc(int r)
- {
- if (r == 0) // normal tcc regs
- return 0x5;
- else if (r == 2) // normal tcc regs
- return 0x1;
- else if (r == 3) // normal tcc regs
- return 0x2;
- else if (r == C67_B2) // normal tcc regs
- return 0x3;
- else if (r == C67_CREG_ZERO)
- return 0; // Special code for no condition reg test
- else
- ALWAYS_ASSERT(FALSE);
- return 0;
- }
- // map TCC reg to C67 reg side A or B
- int C67_map_regs(int r)
- {
- if (r == 0) // normal tcc regs
- return 0x0;
- else if (r == 1) // normal tcc regs
- return 0x0;
- else if (r == 2) // normal tcc regs
- return 0x1;
- else if (r == 3) // normal tcc regs
- return 0x1;
- else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
- return (r & 2) >> 1;
- else if (r == C67_A0)
- return 0; // set to A side
- else if (r == C67_B2)
- return 1; // set to B side
- else if (r == C67_B3)
- return 1; // set to B side
- else if (r == C67_SP)
- return 0x1; // set to SP (B15) B side
- else if (r == C67_FP)
- return 0x0; // set to FP (A15) A side
- else
- ALWAYS_ASSERT(FALSE);
- return 0;
- }
- int C67_map_S12(char *s)
- {
- if (strstr(s, ".S1") != NULL)
- return 0;
- else if (strcmp(s, ".S2"))
- return 1;
- else
- ALWAYS_ASSERT(FALSE);
- return 0;
- }
- int C67_map_D12(char *s)
- {
- if (strstr(s, ".D1") != NULL)
- return 0;
- else if (strcmp(s, ".D2"))
- return 1;
- else
- ALWAYS_ASSERT(FALSE);
- return 0;
- }
- void C67_asm(char *s, int a, int b, int c)
- {
- BOOL xpath;
- #ifdef ASSEMBLY_LISTING_C67
- if (!f) {
- f = fopen("TCC67_out.txt", "wt");
- }
- fprintf(f, "%04X ", ind);
- #endif
- if (strstr(s, "MVKL") == s) {
- C67_g((C67_map_regn(b) << 23) |
- ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1));
- } else if (strstr(s, "MVKH") == s) {
- C67_g((C67_map_regn(b) << 23) |
- (((a >> 16) & 0xffff) << 7) |
- (0x1a << 2) | (C67_map_regs(b) << 1));
- } else if (strstr(s, "STW.D SP POST DEC") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (15 << 18) | //SP B15
- (2 << 13) | //ucst5 (must keep 8 byte boundary !!)
- (0xa << 9) | //mode a = post dec ucst
- (0 << 8) | //r (LDDW bit 0)
- (1 << 7) | //y D1/D2 use B side
- (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STB.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STH.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STB.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STH.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STW.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STW.D *") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (C67_map_regn(b) << 18) | //base reg A0
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(b) << 7) | //y D1/D2 base reg side
- (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STH.D *") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (C67_map_regn(b) << 18) | //base reg A0
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(b) << 7) | //y D1/D2 base reg side
- (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STB.D *") == s) {
- C67_g((C67_map_regn(a) << 23) | //src
- (C67_map_regn(b) << 18) | //base reg A0
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(b) << 7) | //y D1/D2 base reg side
- (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "STW.D +*") == s) {
- ALWAYS_ASSERT(c < 32);
- C67_g((C67_map_regn(a) << 23) | //src
- (C67_map_regn(b) << 18) | //base reg A0
- (c << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(b) << 7) | //y D1/D2 base reg side
- (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of src
- (0 << 0)); //parallel
- } else if (strstr(s, "LDW.D SP PRE INC") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg B15
- (2 << 13) | //ucst5 (must keep 8 byte boundary)
- (9 << 9) | //mode 9 = pre inc ucst5
- (0 << 8) | //r (LDDW bit 0)
- (1 << 7) | //y D1/D2 B side
- (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDDW.D SP PRE INC") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg B15
- (1 << 13) | //ucst5 (must keep 8 byte boundary)
- (9 << 9) | //mode 9 = pre inc ucst5
- (1 << 8) | //r (LDDW bit 1)
- (1 << 7) | //y D1/D2 B side
- (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDW.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDDW.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (1 << 8) | //r (LDDW bit 1)
- (0 << 7) | //y D1/D2 A side
- (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDH.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDB.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDHU.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDBU.D *+SP[A0]") == s) {
- C67_g((C67_map_regn(a) << 23) | //dst
- (15 << 18) | //base reg A15
- (0 << 13) | //offset reg A0
- (5 << 9) | //mode 5 = pos offset, base reg + off reg
- (0 << 8) | //r (LDDW bit 0)
- (0 << 7) | //y D1/D2 A side
- (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(a) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDW.D *") == s) {
- C67_g((C67_map_regn(b) << 23) | //dst
- (C67_map_regn(a) << 18) | //base reg A15
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(a) << 7) | //y D1/D2 src side
- (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDDW.D *") == s) {
- C67_g((C67_map_regn(b) << 23) | //dst
- (C67_map_regn(a) << 18) | //base reg A15
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (1 << 8) | //r (LDDW bit 1)
- (C67_map_regs(a) << 7) | //y D1/D2 src side
- (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDH.D *") == s) {
- C67_g((C67_map_regn(b) << 23) | //dst
- (C67_map_regn(a) << 18) | //base reg A15
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(a) << 7) | //y D1/D2 src side
- (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDB.D *") == s) {
- C67_g((C67_map_regn(b) << 23) | //dst
- (C67_map_regn(a) << 18) | //base reg A15
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(a) << 7) | //y D1/D2 src side
- (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDHU.D *") == s) {
- C67_g((C67_map_regn(b) << 23) | //dst
- (C67_map_regn(a) << 18) | //base reg A15
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(a) << 7) | //y D1/D2 src side
- (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDBU.D *") == s) {
- C67_g((C67_map_regn(b) << 23) | //dst
- (C67_map_regn(a) << 18) | //base reg A15
- (0 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(a) << 7) | //y D1/D2 src side
- (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "LDW.D +*") == s) {
- C67_g((C67_map_regn(b) << 23) | //dst
- (C67_map_regn(a) << 18) | //base reg A15
- (1 << 13) | //cst5
- (1 << 9) | //mode 1 = pos cst offset
- (0 << 8) | //r (LDDW bit 0)
- (C67_map_regs(a) << 7) | //y D1/D2 src side
- (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
- (1 << 2) | //opcode
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPLTSP") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x3a << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPGTSP") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x39 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPEQSP") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x38 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- }
- else if (strstr(s, "CMPLTDP") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x2a << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPGTDP") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x29 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPEQDP") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x28 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPLT") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x57 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPGT") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x47 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPEQ") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x53 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPLTU") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x5f << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "CMPGTU") == s) {
- xpath = C67_map_regs(a) ^ C67_map_regs(b);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x use cross path for src2
- (0x4f << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side for reg c
- (0 << 0)); //parallel
- } else if (strstr(s, "B DISP") == s) {
- C67_g((0 << 29) | //creg
- (0 << 28) | //z
- (a << 7) | //cnst
- (0x4 << 2) | //opcode fixed
- (0 << 1) | //S0/S1
- (0 << 0)); //parallel
- } else if (strstr(s, "B.") == s) {
- xpath = C67_map_regs(c) ^ 1;
- C67_g((C67_map_regc(b) << 29) | //creg
- (a << 28) | //inv
- (0 << 23) | //dst
- (C67_map_regn(c) << 18) | //src2
- (0 << 13) | //
- (xpath << 12) | //x cross path if !B side
- (0xd << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (1 << 1) | //must be S2
- (0 << 0)); //parallel
- } else if (strstr(s, "MV.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (0 << 13) | //src1 (cst5)
- (xpath << 12) | //x cross path if opposite sides
- (0x2 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SPTRUNC.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (0 << 13) | //src1 NA
- (xpath << 12) | //x cross path if opposite sides
- (0xb << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "DPTRUNC.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
- (0 << 13) | //src1 NA
- (xpath << 12) | //x cross path if opposite sides
- (0x1 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "INTSP.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (0 << 13) | //src1 NA
- (xpath << 12) | //x cross path if opposite sides
- (0x4a << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "INTSPU.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (0 << 13) | //src1 NA
- (xpath << 12) | //x cross path if opposite sides
- (0x49 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "INTDP.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (0 << 13) | //src1 NA
- (xpath << 12) | //x cross path if opposite sides
- (0x39 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "INTDPU.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
- (0 << 13) | //src1 NA
- (xpath << 12) | //x cross path if opposite sides
- (0x3b << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SPDP.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (0 << 13) | //src1 NA
- (xpath << 12) | //x cross path if opposite sides
- (0x2 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "DPSP.L") == s) {
- ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
- (0 << 13) | //src1 NA
- (0 << 12) | //x cross path if opposite sides
- (0x9 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "ADD.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x3 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SUB.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x7 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "OR.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x7f << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "AND.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x7b << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "XOR.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x6f << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "ADDSP.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x10 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "ADDDP.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x18 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SUBSP.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x11 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SUBDP.L") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x19 << 5) | //opcode
- (0x6 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "MPYSP.M") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x1c << 7) | //opcode
- (0x0 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "MPYDP.M") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2 (possible x path)
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x0e << 7) | //opcode
- (0x0 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "MPYI.M") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1 (cst5)
- (xpath << 12) | //x cross path if opposite sides
- (0x4 << 7) | //opcode
- (0x0 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SHR.S") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x37 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SHRU.S") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x27 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "SHL.S") == s) {
- xpath = C67_map_regs(b) ^ C67_map_regs(c);
- ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(c) << 23) | //dst
- (C67_map_regn(b) << 18) | //src2
- (C67_map_regn(a) << 13) | //src1
- (xpath << 12) | //x cross path if opposite sides
- (0x33 << 6) | //opcode
- (0x8 << 2) | //opcode fixed
- (C67_map_regs(c) << 1) | //side of dest
- (0 << 0)); //parallel
- } else if (strstr(s, "||ADDK") == s) {
- xpath = 0; // no xpath required just use the side of the src/dst
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(b) << 23) | //dst
- (a << 07) | //scst16
- (0x14 << 2) | //opcode fixed
- (C67_map_regs(b) << 1) | //side of dst
- (1 << 0)); //parallel
- } else if (strstr(s, "ADDK") == s) {
- xpath = 0; // no xpath required just use the side of the src/dst
- C67_g((0 << 29) | //creg
- (0 << 28) | //inv
- (C67_map_regn(b) << 23) | //dst
- (a << 07) | //scst16
- (0x14 << 2) | //opcode fixed
- (C67_map_regs(b) << 1) | //side of dst
- (0 << 0)); //parallel
- } else if (strstr(s, "NOP") == s) {
- C67_g(((a - 1) << 13) | //no of cycles
- (0 << 0)); //parallel
- } else
- ALWAYS_ASSERT(FALSE);
- #ifdef ASSEMBLY_LISTING_C67
- fprintf(f, " %s %d %d %d\n", s, a, b, c);
- #endif
- }
- //r=reg to load, fr=from reg, symbol for relocation, constant
- void C67_MVKL(int r, int fc)
- {
- C67_asm("MVKL.", fc, r, 0);
- }
- void C67_MVKH(int r, int fc)
- {
- C67_asm("MVKH.", fc, r, 0);
- }
- void C67_STB_SP_A0(int r)
- {
- C67_asm("STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0]
- }
- void C67_STH_SP_A0(int r)
- {
- C67_asm("STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0]
- }
- void C67_STW_SP_A0(int r)
- {
- C67_asm("STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0]
- }
- void C67_STB_PTR(int r, int r2)
- {
- C67_asm("STB.D *", r, r2, 0); // STB r, *r2
- }
- void C67_STH_PTR(int r, int r2)
- {
- C67_asm("STH.D *", r, r2, 0); // STH r, *r2
- }
- void C67_STW_PTR(int r, int r2)
- {
- C67_asm("STW.D *", r, r2, 0); // STW r, *r2
- }
- void C67_STW_PTR_PRE_INC(int r, int r2, int n)
- {
- C67_asm("STW.D +*", r, r2, n); // STW r, *+r2
- }
- void C67_PUSH(int r)
- {
- C67_asm("STW.D SP POST DEC", r, 0, 0); // STW r,*SP--
- }
- void C67_LDW_SP_A0(int r)
- {
- C67_asm("LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r
- }
- void C67_LDDW_SP_A0(int r)
- {
- C67_asm("LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r
- }
- void C67_LDH_SP_A0(int r)
- {
- C67_asm("LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r
- }
- void C67_LDB_SP_A0(int r)
- {
- C67_asm("LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r
- }
- void C67_LDHU_SP_A0(int r)
- {
- C67_asm("LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r
- }
- void C67_LDBU_SP_A0(int r)
- {
- C67_asm("LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r
- }
- void C67_LDW_PTR(int r, int r2)
- {
- C67_asm("LDW.D *", r, r2, 0); // LDW *r,r2
- }
- void C67_LDDW_PTR(int r, int r2)
- {
- C67_asm("LDDW.D *", r, r2, 0); // LDDW *r,r2
- }
- void C67_LDH_PTR(int r, int r2)
- {
- C67_asm("LDH.D *", r, r2, 0); // LDH *r,r2
- }
- void C67_LDB_PTR(int r, int r2)
- {
- C67_asm("LDB.D *", r, r2, 0); // LDB *r,r2
- }
- void C67_LDHU_PTR(int r, int r2)
- {
- C67_asm("LDHU.D *", r, r2, 0); // LDHU *r,r2
- }
- void C67_LDBU_PTR(int r, int r2)
- {
- C67_asm("LDBU.D *", r, r2, 0); // LDBU *r,r2
- }
- void C67_LDW_PTR_PRE_INC(int r, int r2)
- {
- C67_asm("LDW.D +*", r, r2, 0); // LDW *+r,r2
- }
- void C67_POP(int r)
- {
- C67_asm("LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r
- }
- void C67_POP_DW(int r)
- {
- C67_asm("LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r
- }
- void C67_CMPLT(int s1, int s2, int dst)
- {
- C67_asm("CMPLT.L1", s1, s2, dst);
- }
- void C67_CMPGT(int s1, int s2, int dst)
- {
- C67_asm("CMPGT.L1", s1, s2, dst);
- }
- void C67_CMPEQ(int s1, int s2, int dst)
- {
- C67_asm("CMPEQ.L1", s1, s2, dst);
- }
- void C67_CMPLTU(int s1, int s2, int dst)
- {
- C67_asm("CMPLTU.L1", s1, s2, dst);
- }
- void C67_CMPGTU(int s1, int s2, int dst)
- {
- C67_asm("CMPGTU.L1", s1, s2, dst);
- }
- void C67_CMPLTSP(int s1, int s2, int dst)
- {
- C67_asm("CMPLTSP.S1", s1, s2, dst);
- }
- void C67_CMPGTSP(int s1, int s2, int dst)
- {
- C67_asm("CMPGTSP.S1", s1, s2, dst);
- }
- void C67_CMPEQSP(int s1, int s2, int dst)
- {
- C67_asm("CMPEQSP.S1", s1, s2, dst);
- }
- void C67_CMPLTDP(int s1, int s2, int dst)
- {
- C67_asm("CMPLTDP.S1", s1, s2, dst);
- }
- void C67_CMPGTDP(int s1, int s2, int dst)
- {
- C67_asm("CMPGTDP.S1", s1, s2, dst);
- }
- void C67_CMPEQDP(int s1, int s2, int dst)
- {
- C67_asm("CMPEQDP.S1", s1, s2, dst);
- }
- void C67_IREG_B_REG(int inv, int r1, int r2) // [!R] B r2
- {
- C67_asm("B.S2", inv, r1, r2);
- }
- // call with how many 32 bit words to skip
- // (0 would branch to the branch instruction)
- void C67_B_DISP(int disp) // B +2 Branch with constant displacement
- {
- // Branch point is relative to the 8 word fetch packet
- //
- // we will assume the text section always starts on an 8 word (32 byte boundary)
- //
- // so add in how many words into the fetch packet the branch is
- C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0);
- }
- void C67_NOP(int n)
- {
- C67_asm("NOP", n, 0, 0);
- }
- void C67_ADDK(int n, int r)
- {
- ALWAYS_ASSERT(abs(n) < 32767);
- C67_asm("ADDK", n, r, 0);
- }
- void C67_ADDK_PARALLEL(int n, int r)
- {
- ALWAYS_ASSERT(abs(n) < 32767);
- C67_asm("||ADDK", n, r, 0);
- }
- void C67_Adjust_ADDK(int *inst, int n)
- {
- ALWAYS_ASSERT(abs(n) < 32767);
- *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7);
- }
- void C67_MV(int r, int v)
- {
- C67_asm("MV.L", 0, r, v);
- }
- void C67_DPTRUNC(int r, int v)
- {
- C67_asm("DPTRUNC.L", 0, r, v);
- }
- void C67_SPTRUNC(int r, int v)
- {
- C67_asm("SPTRUNC.L", 0, r, v);
- }
- void C67_INTSP(int r, int v)
- {
- C67_asm("INTSP.L", 0, r, v);
- }
- void C67_INTDP(int r, int v)
- {
- C67_asm("INTDP.L", 0, r, v);
- }
- void C67_INTSPU(int r, int v)
- {
- C67_asm("INTSPU.L", 0, r, v);
- }
- void C67_INTDPU(int r, int v)
- {
- C67_asm("INTDPU.L", 0, r, v);
- }
- void C67_SPDP(int r, int v)
- {
- C67_asm("SPDP.L", 0, r, v);
- }
- void C67_DPSP(int r, int v) // note regs must be on the same side
- {
- C67_asm("DPSP.L", 0, r, v);
- }
- void C67_ADD(int r, int v)
- {
- C67_asm("ADD.L", v, r, v);
- }
- void C67_SUB(int r, int v)
- {
- C67_asm("SUB.L", v, r, v);
- }
- void C67_AND(int r, int v)
- {
- C67_asm("AND.L", v, r, v);
- }
- void C67_OR(int r, int v)
- {
- C67_asm("OR.L", v, r, v);
- }
- void C67_XOR(int r, int v)
- {
- C67_asm("XOR.L", v, r, v);
- }
- void C67_ADDSP(int r, int v)
- {
- C67_asm("ADDSP.L", v, r, v);
- }
- void C67_SUBSP(int r, int v)
- {
- C67_asm("SUBSP.L", v, r, v);
- }
- void C67_MPYSP(int r, int v)
- {
- C67_asm("MPYSP.M", v, r, v);
- }
- void C67_ADDDP(int r, int v)
- {
- C67_asm("ADDDP.L", v, r, v);
- }
- void C67_SUBDP(int r, int v)
- {
- C67_asm("SUBDP.L", v, r, v);
- }
- void C67_MPYDP(int r, int v)
- {
- C67_asm("MPYDP.M", v, r, v);
- }
- void C67_MPYI(int r, int v)
- {
- C67_asm("MPYI.M", v, r, v);
- }
- void C67_SHL(int r, int v)
- {
- C67_asm("SHL.S", r, v, v);
- }
- void C67_SHRU(int r, int v)
- {
- C67_asm("SHRU.S", r, v, v);
- }
- void C67_SHR(int r, int v)
- {
- C67_asm("SHR.S", r, v, v);
- }
- /* load 'r' from value 'sv' */
- void load(int r, SValue * sv)
- {
- int v, t, ft, fc, fr, size = 0, element;
- BOOL Unsigned = FALSE;
- SValue v1;
- fr = sv->r;
- ft = sv->type.t;
- fc = sv->c.i;
- v = fr & VT_VALMASK;
- if (fr & VT_LVAL) {
- if (v == VT_LLOCAL) {
- v1.type.t = VT_INT;
- v1.r = VT_LOCAL | VT_LVAL;
- v1.c.i = fc;
- load(r, &v1);
- fr = r;
- } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
- tcc_error("long double not supported");
- } else if ((ft & VT_TYPE) == VT_BYTE) {
- size = 1;
- } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
- size = 1;
- Unsigned = TRUE;
- } else if ((ft & VT_TYPE) == VT_SHORT) {
- size = 2;
- } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
- size = 2;
- Unsigned = TRUE;
- } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
- size = 8;
- } else {
- size = 4;
- }
- // check if fc is a positive reference on the stack,
- // if it is tcc is referencing what it thinks is a parameter
- // on the stack, so check if it is really in a register.
- if (v == VT_LOCAL && fc > 0) {
- int stack_pos = 8;
- for (t = 0; t < NoCallArgsPassedOnStack; t++) {
- if (fc == stack_pos)
- break;
- stack_pos += TranslateStackToReg[t];
- }
- // param has been pushed on stack, get it like a local var
- fc = ParamLocOnStack[t] - 8;
- }
- if ((fr & VT_VALMASK) < VT_CONST) // check for pure indirect
- {
- if (size == 1) {
- if (Unsigned)
- C67_LDBU_PTR(v, r); // LDBU *v,r
- else
- C67_LDB_PTR(v, r); // LDB *v,r
- } else if (size == 2) {
- if (Unsigned)
- C67_LDHU_PTR(v, r); // LDHU *v,r
- else
- C67_LDH_PTR(v, r); // LDH *v,r
- } else if (size == 4) {
- C67_LDW_PTR(v, r); // LDW *v,r
- } else if (size == 8) {
- C67_LDDW_PTR(v, r); // LDDW *v,r
- }
- C67_NOP(4); // NOP 4
- return;
- } else if (fr & VT_SYM) {
- greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched
- greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
- C67_MVKL(C67_A0, fc); //r=reg to load, constant
- C67_MVKH(C67_A0, fc); //r=reg to load, constant
- if (size == 1) {
- if (Unsigned)
- C67_LDBU_PTR(C67_A0, r); // LDBU *A0,r
- else
- C67_LDB_PTR(C67_A0, r); // LDB *A0,r
- } else if (size == 2) {
- if (Unsigned)
- C67_LDHU_PTR(C67_A0, r); // LDHU *A0,r
- else
- C67_LDH_PTR(C67_A0, r); // LDH *A0,r
- } else if (size == 4) {
- C67_LDW_PTR(C67_A0, r); // LDW *A0,r
- } else if (size == 8) {
- C67_LDDW_PTR(C67_A0, r); // LDDW *A0,r
- }
- C67_NOP(4); // NOP 4
- return;
- } else {
- element = size;
- // divide offset in bytes to create element index
- C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
- C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
- if (size == 1) {
- if (Unsigned)
- C67_LDBU_SP_A0(r); // LDBU r, SP[A0]
- else
- C67_LDB_SP_A0(r); // LDB r, SP[A0]
- } else if (size == 2) {
- if (Unsigned)
- C67_LDHU_SP_A0(r); // LDHU r, SP[A0]
- else
- C67_LDH_SP_A0(r); // LDH r, SP[A0]
- } else if (size == 4) {
- C67_LDW_SP_A0(r); // LDW r, SP[A0]
- } else if (size == 8) {
- C67_LDDW_SP_A0(r); // LDDW r, SP[A0]
- }
- C67_NOP(4); // NOP 4
- return;
- }
- } else {
- if (v == VT_CONST) {
- if (fr & VT_SYM) {
- greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched
- greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
- }
- C67_MVKL(r, fc); //r=reg to load, constant
- C67_MVKH(r, fc); //r=reg to load, constant
- } else if (v == VT_LOCAL) {
- C67_MVKL(r, fc + 8); //r=reg to load, constant C67 stack points to next free
- C67_MVKH(r, fc + 8); //r=reg to load, constant
- C67_ADD(C67_FP, r); // MV v,r v -> r
- } else if (v == VT_CMP) {
- C67_MV(C67_compare_reg, r); // MV v,r v -> r
- } else if (v == VT_JMP || v == VT_JMPI) {
- t = v & 1;
- C67_B_DISP(4); // Branch with constant displacement, skip over this branch, load, nop, load
- C67_MVKL(r, t); // r=reg to load, 0 or 1 (do this while branching)
- C67_NOP(4); // NOP 4
- gsym(fc); // modifies other branches to branch here
- C67_MVKL(r, t ^ 1); // r=reg to load, 0 or 1
- } else if (v != r) {
- C67_MV(v, r); // MV v,r v -> r
- if ((ft & VT_BTYPE) == VT_DOUBLE)
- C67_MV(v + 1, r + 1); // MV v,r v -> r
- }
- }
- }
- /* store register 'r' in lvalue 'v' */
- void store(int r, SValue * v)
- {
- int fr, bt, ft, fc, size, t, element;
- ft = v->type.t;
- fc = v->c.i;
- fr = v->r & VT_VALMASK;
- bt = ft & VT_BTYPE;
- /* XXX: incorrect if float reg to reg */
- if (bt == VT_LDOUBLE) {
- tcc_error("long double not supported");
- } else {
- if (bt == VT_SHORT)
- size = 2;
- else if (bt == VT_BYTE)
- size = 1;
- else if (bt == VT_DOUBLE)
- size = 8;
- else
- size = 4;
- if ((v->r & VT_VALMASK) == VT_CONST) {
- /* constant memory reference */
- if (v->r & VT_SYM) {
- greloc(cur_text_section, v->sym, ind, R_C60LO16); // rem the inst need to be patched
- greloc(cur_text_section, v->sym, ind + 4, R_C60HI16);
- }
- C67_MVKL(C67_A0, fc); //r=reg to load, constant
- C67_MVKH(C67_A0, fc); //r=reg to load, constant
- if (size == 1)
- C67_STB_PTR(r, C67_A0); // STB r, *A0
- else if (size == 2)
- C67_STH_PTR(r, C67_A0); // STH r, *A0
- else if (size == 4 || size == 8)
- C67_STW_PTR(r, C67_A0); // STW r, *A0
- if (size == 8)
- C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1); // STW r, *+A0[1]
- } else if ((v->r & VT_VALMASK) == VT_LOCAL) {
- // check case of storing to passed argument that
- // tcc thinks is on the stack but for C67 is
- // passed as a reg. However it may have been
- // saved to the stack, if that reg was required
- // for a call to a child function
- if (fc > 0) // argument ??
- {
- // walk through sizes and figure which param
- int stack_pos = 8;
- for (t = 0; t < NoCallArgsPassedOnStack; t++) {
- if (fc == stack_pos)
- break;
- stack_pos += TranslateStackToReg[t];
- }
- // param has been pushed on stack, get it like a local var
- fc = ParamLocOnStack[t] - 8;
- }
- if (size == 8)
- element = 4;
- else
- element = size;
- // divide offset in bytes to create word index
- C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
- C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
- if (size == 1)
- C67_STB_SP_A0(r); // STB r, SP[A0]
- else if (size == 2)
- C67_STH_SP_A0(r); // STH r, SP[A0]
- else if (size == 4 || size == 8)
- C67_STW_SP_A0(r); // STW r, SP[A0]
- if (size == 8) {
- C67_ADDK(1, C67_A0); // ADDK 1,A0
- C67_STW_SP_A0(r + 1); // STW r, SP[A0]
- }
- } else {
- if (size == 1)
- C67_STB_PTR(r, fr); // STB r, *fr
- else if (size == 2)
- C67_STH_PTR(r, fr); // STH r, *fr
- else if (size == 4 || size == 8)
- C67_STW_PTR(r, fr); // STW r, *fr
- if (size == 8) {
- C67_STW_PTR_PRE_INC(r + 1, fr, 1); // STW r, *+fr[1]
- }
- }
- }
- }
- /* 'is_jmp' is '1' if it is a jump */
- static void gcall_or_jmp(int is_jmp)
- {
- int r;
- Sym *sym;
- if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
- /* constant case */
- if (vtop->r & VT_SYM) {
- /* relocation case */
- // get add into A0, then start the jump B3
- greloc(cur_text_section, vtop->sym, ind, R_C60LO16); // rem the inst need to be patched
- greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16);
- C67_MVKL(C67_A0, 0); //r=reg to load, constant
- C67_MVKH(C67_A0, 0); //r=reg to load, constant
- C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // B.S2x A0
- if (is_jmp) {
- C67_NOP(5); // simple jump, just put NOP
- } else {
- // Call, must load return address into B3 during delay slots
- sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address
- greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched
- greloc(cur_text_section, sym, ind + 4, R_C60HI16);
- C67_MVKL(C67_B3, 0); //r=reg to load, constant
- C67_MVKH(C67_B3, 0); //r=reg to load, constant
- C67_NOP(3); // put remaining NOPs
- }
- } else {
- /* put an empty PC32 relocation */
- ALWAYS_ASSERT(FALSE);
- }
- } else {
- /* otherwise, indirect call */
- r = gv(RC_INT);
- C67_IREG_B_REG(0, C67_CREG_ZERO, r); // B.S2x r
- if (is_jmp) {
- C67_NOP(5); // simple jump, just put NOP
- } else {
- // Call, must load return address into B3 during delay slots
- sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address
- greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched
- greloc(cur_text_section, sym, ind + 4, R_C60HI16);
- C67_MVKL(C67_B3, 0); //r=reg to load, constant
- C67_MVKH(C67_B3, 0); //r=reg to load, constant
- C67_NOP(3); // put remaining NOPs
- }
- }
- }
- /* Return the number of registers needed to return the struct, or 0 if
- returning via struct pointer. */
- ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
- *ret_align = 1; // Never have to re-align return values for x86-64
- return 0;
- }
- /* generate function call with address in (vtop->t, vtop->c) and free function
- context. Stack entry is popped */
- void gfunc_call(int nb_args)
- {
- int i, r, size = 0;
- int args_sizes[NoCallArgsPassedOnStack];
- if (nb_args > NoCallArgsPassedOnStack) {
- tcc_error("more than 10 function params not currently supported");
- // handle more than 10, put some on the stack
- }
- for (i = 0; i < nb_args; i++) {
- if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
- ALWAYS_ASSERT(FALSE);
- } else {
- /* simple type (currently always same size) */
- /* XXX: implicit cast ? */
- if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
- tcc_error("long long not supported");
- } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
- tcc_error("long double not supported");
- } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
- size = 8;
- } else {
- size = 4;
- }
- // put the parameter into the corresponding reg (pair)
- r = gv(RC_C67_A4 << (2 * i));
- // must put on stack because with 1 pass compiler , no way to tell
- // if an up coming nested call might overwrite these regs
- C67_PUSH(r);
- if (size == 8) {
- C67_STW_PTR_PRE_INC(r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other)
- }
- args_sizes[i] = size;
- }
- vtop--;
- }
- // POP all the params on the stack into registers for the
- // immediate call (in reverse order)
- for (i = nb_args - 1; i >= 0; i--) {
- if (args_sizes[i] == 8)
- C67_POP_DW(TREG_C67_A4 + i * 2);
- else
- C67_POP(TREG_C67_A4 + i * 2);
- }
- gcall_or_jmp(0);
- vtop--;
- }
- // to be compatible with Code Composer for the C67
- // the first 10 parameters must be passed in registers
- // (pairs for 64 bits) starting wit; A4:A5, then B4:B5 and
- // ending with B12:B13.
- //
- // When a call is made, if the caller has its parameters
- // in regs A4-B13 these must be saved before/as the call
- // parameters are loaded and restored upon return (or if/when needed).
- /* generate function prolog of type 't' */
- void gfunc_prolog(CType * func_type)
- {
- int addr, align, size, func_call, i;
- Sym *sym;
- CType *type;
- sym = func_type->ref;
- func_call = sym->f.func_call;
- addr = 8;
- /* if the function returns a structure, then add an
- implicit pointer parameter */
- func_vt = sym->type;
- func_var = (sym->f.func_type == FUNC_ELLIPSIS);
- if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
- func_vc = addr;
- addr += 4;
- }
- NoOfCurFuncArgs = 0;
- /* define parameters */
- while ((sym = sym->next) != NULL) {
- type = &sym->type;
- sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr);
- size = type_size(type, &align);
- size = (size + 3) & ~3;
- // keep track of size of arguments so
- // we can translate where tcc thinks they
- // are on the stack into the appropriate reg
- TranslateStackToReg[NoOfCurFuncArgs] = size;
- NoOfCurFuncArgs++;
- #ifdef FUNC_STRUCT_PARAM_AS_PTR
- /* structs are passed as pointer */
- if ((type->t & VT_BTYPE) == VT_STRUCT) {
- size = 4;
- }
- #endif
- addr += size;
- }
- func_ret_sub = 0;
- /* pascal type call ? */
- if (func_call == FUNC_STDCALL)
- func_ret_sub = addr - 8;
- C67_MV(C67_FP, C67_A0); // move FP -> A0
- C67_MV(C67_SP, C67_FP); // move SP -> FP
- // place all the args passed in regs onto the stack
- loc = 0;
- for (i = 0; i < NoOfCurFuncArgs; i++) {
- ParamLocOnStack[i] = loc; // remember where the param is
- loc += -8;
- C67_PUSH(TREG_C67_A4 + i * 2);
- if (TranslateStackToReg[i] == 8) {
- C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other)
- }
- }
- TotalBytesPushedOnStack = -loc;
- func_sub_sp_offset = ind; // remember where we put the stack instruction
- C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
- C67_PUSH(C67_A0);
- C67_PUSH(C67_B3);
- }
- /* generate function epilog */
- void gfunc_epilog(void)
- {
- {
- int local = (-loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
- C67_POP(C67_B3);
- C67_NOP(4); // NOP wait for load
- C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
- C67_POP(C67_FP);
- C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
- C67_Adjust_ADDK((int *) (cur_text_section->data +
- func_sub_sp_offset),
- -local + TotalBytesPushedOnStack);
- C67_NOP(3); // NOP
- }
- }
- /* generate a jump to a label */
- int gjmp(int t)
- {
- int ind1 = ind;
- if (nocode_wanted)
- return t;
- C67_MVKL(C67_A0, t); //r=reg to load, constant
- C67_MVKH(C67_A0, t); //r=reg to load, constant
- C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0
- C67_NOP(5);
- return ind1;
- }
- /* generate a jump to a fixed address */
- void gjmp_addr(int a)
- {
- Sym *sym;
- // I guess this routine is used for relative short
- // local jumps, for now just handle it as the general
- // case
- // define a label that will be relocated
- sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
- greloc(cur_text_section, sym, ind, R_C60LO16);
- greloc(cur_text_section, sym, ind + 4, R_C60HI16);
- gjmp(0); // place a zero there later the symbol will be added to it
- }
- /* generate a test. set 'inv' to invert test. Stack entry is popped */
- int gtst(int inv, int t)
- {
- int ind1, n;
- int v, *p;
- v = vtop->r & VT_VALMASK;
- if (nocode_wanted) {
- ;
- } else if (v == VT_CMP) {
- /* fast case : can jump directly since flags are set */
- // C67 uses B2 sort of as flags register
- ind1 = ind;
- C67_MVKL(C67_A0, t); //r=reg to load, constant
- C67_MVKH(C67_A0, t); //r=reg to load, constant
- if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg
- C67_compare_reg != TREG_EDX &&
- C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) {
- C67_MV(C67_compare_reg, C67_B2);
- C67_compare_reg = C67_B2;
- }
- C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0
- C67_NOP(5);
- t = ind1; //return where we need to patch
- } else if (v == VT_JMP || v == VT_JMPI) {
- /* && or || optimization */
- if ((v & 1) == inv) {
- /* insert vtop->c jump list in t */
- // I guess the idea is to traverse to the
- // null at the end of the list and store t
- // there
- n = vtop->c.i;
- while (n != 0) {
- p = (int *) (cur_text_section->data + n);
- // extract 32 bit address from MVKH/MVKL
- n = ((*p >> 7) & 0xffff);
- n |= ((*(p + 1) >> 7) & 0xffff) << 16;
- }
- *p |= (t & 0xffff) << 7;
- *(p + 1) |= ((t >> 16) & 0xffff) << 7;
- t = vtop->c.i;
- } else {
- t = gjmp(t);
- gsym(vtop->c.i);
- }
- }
- vtop--;
- return t;
- }
- /* generate an integer binary operation */
- void gen_opi(int op)
- {
- int r, fr, opc, t;
- switch (op) {
- case '+':
- case TOK_ADDC1: /* add with carry generation */
- opc = 0;
- gen_op8:
- // C67 can't do const compares, must load into a reg
- // so just go to gv2 directly - tktk
- if (op >= TOK_ULT && op <= TOK_GT)
- gv2(RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU
- else
- gv2(RC_INT, RC_INT);
- r = vtop[-1].r;
- fr = vtop[0].r;
- C67_compare_reg = C67_B2;
- if (op == TOK_LT) {
- C67_CMPLT(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_GE) {
- C67_CMPLT(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else if (op == TOK_GT) {
- C67_CMPGT(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_LE) {
- C67_CMPGT(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else if (op == TOK_EQ) {
- C67_CMPEQ(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_NE) {
- C67_CMPEQ(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else if (op == TOK_ULT) {
- C67_CMPLTU(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_UGE) {
- C67_CMPLTU(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else if (op == TOK_UGT) {
- C67_CMPGTU(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_ULE) {
- C67_CMPGTU(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else if (op == '+')
- C67_ADD(fr, r); // ADD r,fr,r
- else if (op == '-')
- C67_SUB(fr, r); // SUB r,fr,r
- else if (op == '&')
- C67_AND(fr, r); // AND r,fr,r
- else if (op == '|')
- C67_OR(fr, r); // OR r,fr,r
- else if (op == '^')
- C67_XOR(fr, r); // XOR r,fr,r
- else
- ALWAYS_ASSERT(FALSE);
- vtop--;
- if (op >= TOK_ULT && op <= TOK_GT) {
- vtop->r = VT_CMP;
- vtop->c.i = op;
- }
- break;
- case '-':
- case TOK_SUBC1: /* sub with carry generation */
- opc = 5;
- goto gen_op8;
- case TOK_ADDC2: /* add with carry use */
- opc = 2;
- goto gen_op8;
- case TOK_SUBC2: /* sub with carry use */
- opc = 3;
- goto gen_op8;
- case '&':
- opc = 4;
- goto gen_op8;
- case '^':
- opc = 6;
- goto gen_op8;
- case '|':
- opc = 1;
- goto gen_op8;
- case '*':
- case TOK_UMULL:
- gv2(RC_INT, RC_INT);
- r = vtop[-1].r;
- fr = vtop[0].r;
- vtop--;
- C67_MPYI(fr, r); // 32 bit multiply fr,r,fr
- C67_NOP(8); // NOP 8 for worst case
- break;
- case TOK_SHL:
- gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
- r = vtop[-1].r;
- fr = vtop[0].r;
- vtop--;
- C67_SHL(fr, r); // arithmetic/logical shift
- break;
- case TOK_SHR:
- gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
- r = vtop[-1].r;
- fr = vtop[0].r;
- vtop--;
- C67_SHRU(fr, r); // logical shift
- break;
- case TOK_SAR:
- gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
- r = vtop[-1].r;
- fr = vtop[0].r;
- vtop--;
- C67_SHR(fr, r); // arithmetic shift
- break;
- case '/':
- t = TOK__divi;
- call_func:
- vswap();
- /* call generic idiv function */
- vpush_global_sym(&func_old_type, t);
- vrott(3);
- gfunc_call(2);
- vpushi(0);
- vtop->r = REG_IRET;
- vtop->r2 = VT_CONST;
- break;
- case TOK_UDIV:
- case TOK_PDIV:
- t = TOK__divu;
- goto call_func;
- case '%':
- t = TOK__remi;
- goto call_func;
- case TOK_UMOD:
- t = TOK__remu;
- goto call_func;
- default:
- opc = 7;
- goto gen_op8;
- }
- }
- /* generate a floating point operation 'v = t1 op t2' instruction. The
- two operands are guaranteed to have the same floating point type */
- /* XXX: need to use ST1 too */
- void gen_opf(int op)
- {
- int ft, fc, fr, r;
- if (op >= TOK_ULT && op <= TOK_GT)
- gv2(RC_EDX, RC_EAX); // make sure src2 is on b side
- else
- gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
- ft = vtop->type.t;
- fc = vtop->c.i;
- r = vtop->r;
- fr = vtop[-1].r;
- if ((ft & VT_BTYPE) == VT_LDOUBLE)
- tcc_error("long doubles not supported");
- if (op >= TOK_ULT && op <= TOK_GT) {
- r = vtop[-1].r;
- fr = vtop[0].r;
- C67_compare_reg = C67_B2;
- if (op == TOK_LT) {
- if ((ft & VT_BTYPE) == VT_DOUBLE)
- C67_CMPLTDP(r, fr, C67_B2);
- else
- C67_CMPLTSP(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_GE) {
- if ((ft & VT_BTYPE) == VT_DOUBLE)
- C67_CMPLTDP(r, fr, C67_B2);
- else
- C67_CMPLTSP(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else if (op == TOK_GT) {
- if ((ft & VT_BTYPE) == VT_DOUBLE)
- C67_CMPGTDP(r, fr, C67_B2);
- else
- C67_CMPGTSP(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_LE) {
- if ((ft & VT_BTYPE) == VT_DOUBLE)
- C67_CMPGTDP(r, fr, C67_B2);
- else
- C67_CMPGTSP(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else if (op == TOK_EQ) {
- if ((ft & VT_BTYPE) == VT_DOUBLE)
- C67_CMPEQDP(r, fr, C67_B2);
- else
- C67_CMPEQSP(r, fr, C67_B2);
- C67_invert_test = FALSE;
- } else if (op == TOK_NE) {
- if ((ft & VT_BTYPE) == VT_DOUBLE)
- C67_CMPEQDP(r, fr, C67_B2);
- else
- C67_CMPEQSP(r, fr, C67_B2);
- C67_invert_test = TRUE;
- } else {
- ALWAYS_ASSERT(FALSE);
- }
- vtop->r = VT_CMP; // tell TCC that result is in "flags" actually B2
- } else {
- if (op == '+') {
- if ((ft & VT_BTYPE) == VT_DOUBLE) {
- C67_ADDDP(r, fr); // ADD fr,r,fr
- C67_NOP(6);
- } else {
- C67_ADDSP(r, fr); // ADD fr,r,fr
- C67_NOP(3);
- }
- vtop--;
- } else if (op == '-') {
- if ((ft & VT_BTYPE) == VT_DOUBLE) {
- C67_SUBDP(r, fr); // SUB fr,r,fr
- C67_NOP(6);
- } else {
- C67_SUBSP(r, fr); // SUB fr,r,fr
- C67_NOP(3);
- }
- vtop--;
- } else if (op == '*') {
- if ((ft & VT_BTYPE) == VT_DOUBLE) {
- C67_MPYDP(r, fr); // MPY fr,r,fr
- C67_NOP(9);
- } else {
- C67_MPYSP(r, fr); // MPY fr,r,fr
- C67_NOP(3);
- }
- vtop--;
- } else if (op == '/') {
- if ((ft & VT_BTYPE) == VT_DOUBLE) {
- // must call intrinsic DP floating point divide
- vswap();
- /* call generic idiv function */
- vpush_global_sym(&func_old_type, TOK__divd);
- vrott(3);
- gfunc_call(2);
- vpushi(0);
- vtop->r = REG_FRET;
- vtop->r2 = REG_LRET;
- } else {
- // must call intrinsic SP floating point divide
- vswap();
- /* call generic idiv function */
- vpush_global_sym(&func_old_type, TOK__divf);
- vrott(3);
- gfunc_call(2);
- vpushi(0);
- vtop->r = REG_FRET;
- vtop->r2 = VT_CONST;
- }
- } else
- ALWAYS_ASSERT(FALSE);
- }
- }
- /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
- and 'long long' cases. */
- void gen_cvt_itof(int t)
- {
- int r;
- gv(RC_INT);
- r = vtop->r;
- if ((t & VT_BTYPE) == VT_DOUBLE) {
- if (t & VT_UNSIGNED)
- C67_INTDPU(r, r);
- else
- C67_INTDP(r, r);
- C67_NOP(4);
- vtop->type.t = VT_DOUBLE;
- } else {
- if (t & VT_UNSIGNED)
- C67_INTSPU(r, r);
- else
- C67_INTSP(r, r);
- C67_NOP(3);
- vtop->type.t = VT_FLOAT;
- }
- }
- /* convert fp to int 't' type */
- /* XXX: handle long long case */
- void gen_cvt_ftoi(int t)
- {
- int r;
- gv(RC_FLOAT);
- r = vtop->r;
- if (t != VT_INT)
- tcc_error("long long not supported");
- else {
- if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
- C67_DPTRUNC(r, r);
- C67_NOP(3);
- } else {
- C67_SPTRUNC(r, r);
- C67_NOP(3);
- }
- vtop->type.t = VT_INT;
- }
- }
- /* convert from one floating point type to another */
- void gen_cvt_ftof(int t)
- {
- int r, r2;
- if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
- (t & VT_BTYPE) == VT_FLOAT) {
- // convert double to float
- gv(RC_FLOAT); // get it in a register pair
- r = vtop->r;
- C67_DPSP(r, r); // convert it to SP same register
- C67_NOP(3);
- vtop->type.t = VT_FLOAT;
- vtop->r2 = VT_CONST; // set this as unused
- } else if ((vtop->type.t & VT_BTYPE) == VT_FLOAT &&
- (t & VT_BTYPE) == VT_DOUBLE) {
- // convert float to double
- gv(RC_FLOAT); // get it in a register
- r = vtop->r;
- if (r == TREG_EAX) { // make sure the paired reg is avail
- r2 = get_reg(RC_ECX);
- } else if (r == TREG_EDX) {
- r2 = get_reg(RC_ST0);
- } else {
- ALWAYS_ASSERT(FALSE);
- r2 = 0; /* avoid warning */
- }
- C67_SPDP(r, r); // convert it to DP same register
- C67_NOP(1);
- vtop->type.t = VT_DOUBLE;
- vtop->r2 = r2; // set this as unused
- } else {
- ALWAYS_ASSERT(FALSE);
- }
- }
- /* computed goto support */
- void ggoto(void)
- {
- gcall_or_jmp(1);
- vtop--;
- }
- /* Save the stack pointer onto the stack and return the location of its address */
- ST_FUNC void gen_vla_sp_save(int addr) {
- tcc_error("variable length arrays unsupported for this target");
- }
- /* Restore the SP from a location on the stack */
- ST_FUNC void gen_vla_sp_restore(int addr) {
- tcc_error("variable length arrays unsupported for this target");
- }
- /* Subtract from the stack pointer, and push the resulting value onto the stack */
- ST_FUNC void gen_vla_alloc(CType *type, int align) {
- tcc_error("variable length arrays unsupported for this target");
- }
- /* end of C67 code generator */
- /*************************************************************/
- #endif
- /*************************************************************/
|