Changeset 572

Show
Ignore:
Timestamp:
07/04/10 00:32:30 (2 years ago)
Author:
walter
Message:

start on 64 bit assembler

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/backend/code.h

    r569 r572  
    369369#define CFjmp16           2     // need 16 bit jump offset (long branch) 
    370370#define CFtarg            4     // this code is the target of a jump 
    371371#define CFseg             8     // get segment of immediate value 
    372372#define CFoff          0x10     // get offset of immediate value 
    373373#define CFss           0x20     // generate an SS: segment override (not with 
    374374                                // CFes at the same time, though!) 
    375375#define CFpsw          0x40     // we need the flags result after this instruction 
    376376#define CFopsize       0x80     // prefix with operand size 
    377377#define CFaddrsize    0x100     // prefix with address size 
    378378#define CFds          0x200     // need DS override (not with es, ss, or cs ) 
    379379#define CFcs          0x400     // need CS override 
    380380#define CFfs          0x800     // need FS override 
    381381#define CFgs    (CFcs | CFfs)   // need GS override 
    382382#define CFwait       0x1000     // If I32 it indicates when to output a WAIT 
    383383#define CFselfrel    0x2000     // if self-relative 
    384384#define CFunambig    0x4000     // indicates cannot be accessed by other addressing 
    385385                                // modes 
    386386#define CFtarg2      0x8000     // like CFtarg, but we can't optimize this away 
    387387#define CFvolatile  0x10000     // volatile reference, do not schedule 
    388388#define CFclassinit 0x20000     // class init code 
     389#define CFoffset64  0x40000     // offset is 64 bits 
    389390 
    390391#define CFPREFIX (CFSEG | CFopsize | CFaddrsize) 
    391392#define CFSEG   (CFes | CFss | CFds | CFcs | CFfs | CFgs) 
    392393 
    393394    unsigned char Irex;         // REX prefix 
    394395 
    395396    unsigned char Iop; 
    396397    unsigned char Irm;          // reg/mode 
    397398 
    398399    unsigned char Iop2;         // second opcode byte 
    399400    unsigned char Isib;         // SIB byte 
    400401 
    401402    unsigned char Iop3;         // third opcode byte 
    402403 
    403404    unsigned char IFL1,IFL2;    // FLavors of 1st, 2nd operands 
    404405    union evc IEV1;             // 1st operand, if any 
    405406      #define IEVpointer1 IEV1._EP.Vpointer 
    406407      #define IEVseg1     IEV1._EP.Vseg 
    407408      #define IEVsym1     IEV1.sp.Vsym 
    408409      #define IEVdsym1    IEV1.dsp.Vsym 
  • branches/dmd-1.x/src/backend/el.h

    r442 r572  
    11// Copyright (C) 1985-1995 by Symantec 
    2 // Copyright (C) 2000-2009 by Digital Mars 
     2// Copyright (C) 2000-2010 by Digital Mars 
    33// All Rights Reserved 
    44// http://www.digitalmars.com 
    55// Written by Walter Bright 
    66/* 
    77 * This source file is made available for personal use 
    88 * only. The license is in /dmd/src/dmd/backendlicense.txt 
    99 * or /dm/src/dmd/backendlicense.txt 
    1010 * For any other uses, please contact Digital Mars. 
    1111 */ 
    1212 
    1313/* Routines to handle elems.                            */ 
    1414 
    1515#if __SC__ 
    1616#pragma once 
    1717#endif 
    1818 
    1919#ifndef EL_H 
    2020#define EL_H    1 
    2121 
    2222#if TARGET_MAC 
     
    108108        { 
    109109            // Ety2: Must be in same position as Ety! 
    110110            tym_t Ety2_;                        // data type (TYxxxx) 
    111111            #define Ety2 _EU._EC.Ety2_ 
    112112            unsigned char Ecomsub_;     // number of remaining references to 
    113113                                        // this common subexp (used to determine 
    114114                                        // first, intermediate, and last references 
    115115                                        // to a CSE) 
    116116            #define Ecomsub _EU._EC.Ecomsub_ 
    117117 
    118118#if TARGET_POWERPC 
    119119            unsigned char Gflags; 
    120120            #define     GFLassrval      1               // element is rvalue of an assign 
    121121            #define     GFLsignok       2               // element does not need sign extend 
    122122            #define     GFLstrthis_fixed        4       // strthis child elem has been fixed 
    123123                                                        // on first pass, do not do it again 
    124124#endif 
    125125        }_EC; 
    126126    }_EU; 
    127127 
    128     targ_size_t Enumbytes;      // number of bytes for type if TYstruct | TYarray 
     128    unsigned Enumbytes;         // number of bytes for type if TYstruct | TYarray 
    129129    TARGET_structELEM           // target specific additions 
    130130    Srcpos Esrcpos;             // source file position 
    131131}; 
    132132 
    133133#define typemask(e)     ((!MARS && PARSER) ? (e)->ET->Tty : (e)->Ety ) 
    134134#define typetym(e)      ((e)->ET->Tty) 
    135135#define el_fl(e)        ((enum FL)((e)->EV.sp.Vsym->Sfl)) 
    136136#define Eoffset         EV.sp.Voffset 
    137137#define Esymnum         EV.sp.Vsymnum 
    138138 
    139139#define list_elem(list) ((elem *) list_ptr(list)) 
    140140#define list_setelem(list,ptr) list_ptr(list) = (elem *)(ptr) 
    141141#define cnst(e) ((e)->Eoper == OPconst) /* Determine if elem is a constant */ 
    142142#define E1        EV.eop.Eleft          /* left child                   */ 
    143143#define E2        EV.eop.Eright         /* right child                  */ 
    144144#define Erd       EV.sp.spu.Erd         // reaching definition 
    145145 
    146146#define el_int(a,b)     el_long(a,b) 
    147147  
    148148typedef elem *elem_p;   /* try to reduce the symbol table size  */ 
  • branches/dmd-1.x/src/backend/elfobj.c

    r569 r572  
    4141//#define DEBSYM 0x7E 
    4242 
    4343static Outbuffer *fobjbuf; 
    4444 
    4545regm_t BYTEREGS = BYTEREGS_INIT; 
    4646regm_t ALLREGS = ALLREGS_INIT; 
    4747 
    4848static char __file__[] = __FILE__;      // for tassert.h 
    4949#include        "tassert.h" 
    5050 
    5151#define MATCH_SECTION 1 
    5252 
    5353#define DEST_LEN (IDMAX + IDOHD + 1) 
    5454char *obj_mangle2(Symbol *s,char *dest); 
    5555 
    5656#if MARS 
    5757// C++ name mangling is handled by front end 
    5858#define cpp_mangle(s) ((s)->Sident) 
    5959#endif 
    6060 
     61/*************************************************** 
     62 * Correspondence of relocation types 
     63 *      386             32 bit in 64      64 in 64 
     64 *      RI_TYPE_SYM32   R_X86_64_32       R_X86_64_64 
     65 *      RI_TYPE_GOTOFF  R_X86_64_PC32     R_X86_64_ 
     66 *      RI_TYPE_GOTPC   R_X86_64_         R_X86_64_ 
     67 *      RI_TYPE_GOT32   R_X86_64_         R_X86_64_ 
     68 *      RI_TYPE_TLS_GD  R_X86_64_TLSGD    R_X86_64_ 
     69 *      RI_TYPE_TLS_IE  R_X86_64_GOTTPOFF R_X86_64_ 
     70 *      RI_TYPE_TLS_LE  R_X86_64_TPOFF32  R_X86_64_ 
     71 *      RI_TYPE_PLT32   R_X86_64_PLT32    R_X86_64_ 
     72 *      RI_TYPE_PC32    R_X86_64_PC32     R_X86_64_ 
     73 */ 
    6174 
    6275/****************************************** 
    6376 */ 
    6477 
    6578symbol *GOTsym; // global offset table reference 
    6679 
    6780symbol *elfobj_getGOTsym() 
    6881{ 
    6982    if (!GOTsym) 
    7083    { 
    7184        GOTsym = symbol_name("_GLOBAL_OFFSET_TABLE_",SCglobal,tspvoid); 
    7285    } 
    7386    return GOTsym; 
    7487} 
    7588 
    7689static void objfile_write(FILE *fd, void *buffer, unsigned len); 
    7790 
    7891STATIC char * objmodtoseg (const char *modname); 
    7992STATIC void obj_browse_flush(); 
    8093STATIC void objfixupp (struct FIXUP *); 
    8194STATIC void ledata_new (int seg,targ_size_t offset); 
    82 static int obj_align(Symbol *s); 
    8395void obj_tlssections(); 
    8496 
    8597static IDXSYM elf_addsym(IDXSTR sym, targ_size_t val, unsigned sz, 
    8698                        unsigned typ,unsigned bind,IDXSEC sec); 
    8799static long elf_align(FILE *fd, targ_size_t size, long offset); 
    88100 
    89101// The object file is built is several separate pieces 
    90102 
    91103// Non-repeatable section types have single output buffers 
    92104//      Pre-allocated buffers are defined for: 
    93105//              Section Names string table 
    94106//              Section Headers table 
    95107//              Symbol table 
    96108//              String table 
    97109//              Notes section 
    98110//              Comment data 
    99111 
    100112// Section Names  - String table for section names only 
    101113static Outbuffer *section_names; 
    102114#define SEC_NAMES_INIT  800 
     
    12361248{ 
    12371249    //dbg_printf("obj_exestr(char *%s)\n",p); 
    12381250} 
    12391251 
    12401252/************************** 
    12411253 * Embed string in obj. 
    12421254 */ 
    12431255 
    12441256void obj_user(const char *p) 
    12451257{ 
    12461258    //dbg_printf("obj_user(char *%s)\n",p); 
    12471259} 
    12481260 
    12491261/******************************* 
    12501262 * Output a weak extern record. 
    12511263 */ 
    12521264 
    12531265void obj_wkext(Symbol *s1,Symbol *s2) 
    12541266{ 
    12551267    //dbg_printf("obj_wkext(Symbol *%s,Symbol *s2)\n",s1->Sident,s2->Sident); 
    1256 #if 0 
    1257     char buffer[2+2+2]; 
    1258     int i; 
    1259  
    1260     buffer[0] = 0x80; 
    1261     buffer[1] = 0xA8; 
    1262     i = 2; 
    1263     i += insidx(&buffer[2],s1->Sxtrnnum); 
    1264     i += insidx(&buffer[i],s2->Sxtrnnum); 
    1265     objrecord(COMENT,buffer,i); 
    1266 #endif 
    12671268} 
    12681269 
    12691270/******************************* 
    12701271 * Output file name record. 
    12711272 * 
    12721273 * Currently assumes that obj_filename will not be called 
    12731274 *      twice for the same file. 
    12741275 */ 
    12751276 
    12761277void obj_filename(const char *modname) 
    1277 {   unsigned strtab_idx; 
    1278     unsigned symtab_idx; 
    1279  
     1278
    12801279    //dbg_printf("obj_filename(char *%s)\n",modname); 
    1281     strtab_idx = elf_addstr(symtab_strings,modname); 
     1280    unsigned strtab_idx = elf_addstr(symtab_strings,modname); 
    12821281    elf_addsym(strtab_idx,0,0,STT_FILE,STB_LOCAL,SHT_ABS); 
    12831282} 
    12841283 
    12851284/******************************* 
    12861285 * Embed compiler version in .obj file. 
    12871286 */ 
    12881287 
    12891288void obj_compiler() 
    12901289{ 
    12911290    //dbg_printf("obj_compiler\n"); 
    12921291    comment_data = new Outbuffer(); 
    12931292    comment_data->write(compiler,sizeof(compiler)); 
    12941293    //dbg_printf("Comment data size %d\n",comment_data->size()); 
    12951294} 
    12961295 
    1297 #if 0 
    1298 /******************************** 
    1299  * Convert module name to code segment name. 
    1300  * Output: 
    1301  *      mem_malloc'd code seg name 
    1302  */ 
    1303  
    1304 STATIC char * objmodtoseg(const char *modname) 
    1305 {   char *csegname = NULL; 
    1306  
    1307     if (LARGECODE)              // if need to add in module name 
    1308     {   int i; 
    1309         char *m; 
    1310         static const char suffix[] = "_TEXT"; 
    1311  
    1312         // Prepend the module name to the beginning of the _TEXT 
    1313         m = filespecgetroot(filespecname(modname)); 
    1314         strupr(m); 
    1315         i = strlen(m); 
    1316         csegname = mem_malloc(i + sizeof(suffix)); 
    1317         strcpy(csegname,m); 
    1318         strcat(csegname,suffix); 
    1319         mem_free(m); 
    1320     } 
    1321     return csegname; 
    1322 } 
    1323 #endif 
    13241296 
    13251297//#if NEWSTATICDTOR 
    13261298 
    13271299/************************************** 
    13281300 * Symbol is the function that calls the static constructors. 
    13291301 * Put a pointer to it into a special segment that the startup code 
    13301302 * looks at. 
    13311303 * Input: 
    13321304 *      s       static constructor function 
    13331305 *      dtor    !=0 if leave space for static destructor 
    13341306 *      seg     1:      user 
    13351307 *              2:      lib 
    13361308 *              3:      compiler 
    13371309 */ 
    13381310 
    13391311void obj_staticctor(Symbol *s,int dtor,int none) 
    13401312{ 
    13411313// Static constructors and destructors 
    13421314    IDXSEC seg; 
    13431315    Outbuffer *buf; 
    13441316 
    13451317    //dbg_printf("obj_staticctor(%s) offset %x\n",s->Sident,s->Soffset); 
    13461318    //symbol_print(s); 
    13471319    s->Sseg = seg = 
    13481320        elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, 4); 
    13491321    buf = SegData[seg]->SDbuf; 
    13501322    if (I64) 
    13511323        buf->write64(s->Soffset); 
    13521324    else 
    13531325        buf->write32(s->Soffset); 
    1354     elf_addrel(seg,SegData[seg]->SDoffset,RI_TYPE_SYM32,STI_TEXT,0); 
     1326    elf_addrel(seg,SegData[seg]->SDoffset,I64 ? R_X86_64_64 : RI_TYPE_SYM32,STI_TEXT,0); 
    13551327    SegData[seg]->SDoffset = buf->size(); 
    13561328} 
    13571329 
    13581330/************************************** 
    13591331 * Symbol is the function that calls the static destructors. 
    13601332 * Put a pointer to it into a special segment that the exit code 
    13611333 * looks at. 
    13621334 * Input: 
    13631335 *      s       static destructor function 
    13641336 */ 
    13651337 
    13661338void obj_staticdtor(Symbol *s) 
    13671339{ 
    13681340    IDXSEC seg; 
    13691341    Outbuffer *buf; 
    13701342 
    13711343    //dbg_printf("obj_staticdtor(%s) offset %x\n",s->Sident,s->Soffset); 
    13721344    //symbol_print(s); 
    13731345    seg = elf_getsegment(".dtors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, 4); 
    13741346    buf = SegData[seg]->SDbuf; 
    13751347    if (I64) 
    13761348        buf->write64(s->Soffset); 
    13771349    else 
    13781350        buf->write32(s->Soffset); 
    1379     //elf_addrel(seg,0,RI_TYPE_SYM32,STI_TEXT,0); 
    1380     elf_addrel(seg,SegData[seg]->SDoffset,RI_TYPE_SYM32,s->Sxtrnnum,0); 
     1351    elf_addrel(seg,SegData[seg]->SDoffset,I64 ? R_X86_64_64 : RI_TYPE_SYM32,s->Sxtrnnum,0); 
    13811352    SegData[seg]->SDoffset = buf->size(); 
    13821353} 
    13831354 
    13841355//#else 
    13851356 
    13861357/*************************************** 
    13871358 * Stuff pointer to function in its own segment. 
    13881359 * Used for static ctor and dtor lists. 
    13891360 */ 
    13901361 
    13911362void obj_funcptr(Symbol *s) 
    13921363{ 
    13931364    //dbg_printf("obj_funcptr(%s) \n",s->Sident); 
    13941365} 
    13951366 
    13961367//#endif 
    13971368 
    13981369/*************************************** 
    13991370 * Stuff the following data in a separate segment: 
    14001371 *      pointer to function 
    14011372 *      pointer to ehsym 
    14021373 *      length of function 
    14031374 */ 
    14041375 
    14051376void obj_ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym) 
    14061377{ 
    14071378    //dbg_printf("obj_ehtables(%s) \n",sfunc->Sident); 
    14081379 
    1409     symbol *ehtab_entry; 
    1410     dt_t **pdte; 
    1411  
    1412     ehtab_entry = symbol_generate(SCstatic,type_alloc(TYint)); 
     1380    symbol *ehtab_entry = symbol_generate(SCstatic,type_alloc(TYint)); 
    14131381    symbol_keep(ehtab_entry); 
    14141382    elf_getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14151383    ehtab_entry->Sseg = elf_getsegment(".deh_eh", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14161384    elf_getsegment(".deh_end", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14171385    ehtab_entry->Stype->Tmangle = mTYman_c; 
    14181386    ehsym->Stype->Tmangle = mTYman_c; 
    1419     pdte = &ehtab_entry->Sdt; 
     1387    dt_t **pdte = &ehtab_entry->Sdt; 
    14201388    pdte = dtxoff(pdte,sfunc,0,TYnptr); 
    14211389    pdte = dtxoff(pdte,ehsym,0,TYnptr); 
    14221390    pdte = dtnbytes(pdte,4,(char *)&sfunc->Ssize); 
    14231391    outdata(ehtab_entry); 
    14241392} 
    14251393 
    14261394/********************************************* 
    14271395 * Put out symbols that define the beginning/end of the .deh_eh section. 
    14281396 */ 
    14291397 
    14301398void obj_ehsections() 
    1431 {   int sec; 
    1432     IDXSYM symidx; 
    1433     IDXSTR namidx; 
    1434  
    1435     sec = elf_getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
     1399
     1400    int sec = elf_getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14361401    //obj_bytes(sec, 0, 4, NULL); 
    14371402 
    1438     namidx = elf_addstr(symtab_strings,"_deh_beg"); 
     1403    IDXSTR namidx = elf_addstr(symtab_strings,"_deh_beg"); 
    14391404    elf_addsym(namidx, 0, 0, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec)); 
    14401405    //elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec)); 
    14411406 
    14421407    elf_getsegment(".deh_eh", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14431408 
    14441409    sec = elf_getsegment(".deh_end", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14451410    namidx = elf_addstr(symtab_strings,"_deh_end"); 
    14461411    elf_addsym(namidx, 0, 0, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec)); 
    14471412 
    14481413    obj_tlssections(); 
    14491414} 
    14501415 
    14511416/********************************************* 
    14521417 * Put out symbols that define the beginning/end of the thread local storage sections. 
    14531418 */ 
    14541419 
    14551420void obj_tlssections() 
    14561421{ 
    14571422    IDXSTR namidx; 
    14581423 
     
    16761641 * won't be storing D gc roots in their tls. 
    16771642 * Output: 
    16781643 *      seg_tlsseg      set to segment number for TLS segment. 
    16791644 * Returns: 
    16801645 *      segment for TLS segment 
    16811646 */ 
    16821647 
    16831648seg_data *obj_tlsseg() 
    16841649{ 
    16851650    /* Ensure that ".tdata" precedes any other .tdata. section, as the ld 
    16861651     * linker script fails to work right. 
    16871652     */ 
    16881653    elf_getsegment(".tdata", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
    16891654 
    16901655    static const char tlssegname[] = ".tdata."; 
    16911656    //dbg_printf("obj_tlsseg(\n"); 
    16921657 
    16931658    if (seg_tlsseg == UNKNOWN) 
    16941659    { 
    16951660        seg_tlsseg = elf_getsegment(tlssegname, NULL, SHT_PROGDEF, 
    1696             SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
     1661            SHF_ALLOC|SHF_WRITE|SHF_TLS, I64 ? 16 : 4); 
    16971662    } 
    16981663    return SegData[seg_tlsseg]; 
    16991664} 
    17001665 
    17011666 
    17021667/********************************* 
    17031668 * Define segments for Thread Local Storage. 
    17041669 * Output: 
    17051670 *      seg_tlsseg_bss  set to segment number for TLS segment. 
    17061671 * Returns: 
    17071672 *      segment for TLS segment 
    17081673 */ 
    17091674 
    17101675seg_data *obj_tlsseg_bss() 
    17111676{ 
    17121677    static const char tlssegname[] = ".tbss"; 
    17131678    //dbg_printf("obj_tlsseg_bss(\n"); 
    17141679 
    17151680    if (seg_tlsseg_bss == UNKNOWN) 
    17161681    { 
    17171682        seg_tlsseg_bss = elf_getsegment(tlssegname, NULL, SHT_NOBITS, 
    1718             SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
     1683            SHF_ALLOC|SHF_WRITE|SHF_TLS, I64 ? 16 : 4); 
    17191684    } 
    17201685    return SegData[seg_tlsseg_bss]; 
    17211686} 
    17221687 
    17231688 
    17241689/******************************* 
    17251690 * Output an alias definition record. 
    17261691 */ 
    17271692 
    17281693void obj_alias(const char *n1,const char *n2) 
    1729 {   unsigned len; 
    1730     char *buffer; 
    1731  
     1694
    17321695    dbg_printf("obj_alias(%s,%s)\n",n1,n2); 
    17331696    assert(0); 
    17341697#if NOT_DONE 
    1735     buffer = (char *) alloca(strlen(n1) + strlen(n2) + 2 * ONS_OHD); 
    1736     len = obj_namestring(buffer,n1); 
     1698    char *buffer = (char *) alloca(strlen(n1) + strlen(n2) + 2 * ONS_OHD); 
     1699    unsigned len = obj_namestring(buffer,n1); 
    17371700    len += obj_namestring(buffer + len,n2); 
    17381701    objrecord(ALIAS,buffer,len); 
    17391702#endif 
    17401703} 
    17411704 
    1742 char *unsstr (unsigned value) 
    1743 { 
    1744     static char buffer [64]; 
    1745  
    1746     sprintf (buffer, "%d", value); 
     1705char *unsstr(unsigned value) 
     1706{ 
     1707    static char buffer[64]; 
     1708 
     1709    sprintf(buffer, "%d", value); 
    17471710    return buffer; 
    17481711} 
    17491712 
    17501713/******************************* 
    17511714 * Mangle a name. 
    17521715 * Returns: 
    17531716 *      mangled name 
    17541717 */ 
    17551718 
    17561719char *obj_mangle2(Symbol *s,char *dest) 
    17571720{ 
    1758     size_t len; 
    17591721    char *name; 
    17601722 
    17611723    //dbg_printf("obj_mangle('%s'), mangle = x%x\n",s->Sident,type_mangle(s->Stype)); 
    17621724    symbol_debug(s); 
    17631725    assert(dest); 
    17641726#if SCPP 
    17651727    name = CPP ? cpp_mangle(s) : s->Sident; 
    17661728#elif MARS 
    17671729    name = cpp_mangle(s); 
    17681730#else 
    17691731    name = s->Sident; 
    17701732#endif 
    1771     len = strlen(name);                 // # of bytes in name 
     1733    size_t len = strlen(name);                 // # of bytes in name 
    17721734    //dbg_printf("len %d\n",len); 
    17731735    switch (type_mangle(s->Stype)) 
    17741736    { 
    17751737        case mTYman_pas:                // if upper case 
    17761738        case mTYman_for: 
    17771739            if (len >= DEST_LEN) 
    17781740                dest = (char *)mem_malloc(len + 1); 
    17791741            memcpy(dest,name,len + 1);  // copy in name and ending 0 
    17801742            for (int i = 0; 1; i++) 
    17811743            {   char c = dest[i]; 
    17821744                if (!c) 
    17831745                    break; 
    17841746                if (c >= 'a' && c <= 'z') 
    17851747                    dest[i] = c + 'A' - 'a'; 
    17861748            } 
    17871749            break; 
    17881750        case mTYman_std: 
    17891751#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS 
    17901752            if (tyfunc(s->ty()) && !variadic(s->Stype)) 
    17911753#else 
     
    18151777            memcpy(dest,name,len+1);// copy in name and trailing 0 
    18161778            break; 
    18171779 
    18181780        default: 
    18191781#ifdef DEBUG 
    18201782            printf("mangling %x\n",type_mangle(s->Stype)); 
    18211783            symbol_print(s); 
    18221784#endif 
    18231785            printf("%d\n", type_mangle(s->Stype)); 
    18241786            assert(0); 
    18251787    } 
    18261788    //dbg_printf("\t %s\n",dest); 
    18271789    return dest; 
    18281790} 
    18291791 
    18301792/******************************* 
    18311793 * Export a function name. 
    18321794 */ 
    18331795 
    18341796void obj_export(Symbol *s,unsigned argsize) 
    1835 {   char *coment; 
    1836     size_t len; 
    1837  
     1797
    18381798    //dbg_printf("obj_export(%s,%d)\n",s->Sident,argsize); 
    18391799 
    18401800} 
    18411801 
    18421802/******************************* 
    18431803 * Update data information about symbol 
    18441804 *      align for output and assign segment 
    18451805 *      if not already specified. 
    18461806 * 
    18471807 * Input: 
    18481808 *      sdata           data symbol 
    18491809 *      datasize        output size 
    18501810 *      seg             default seg if not known 
    18511811 * Returns: 
    18521812 *      actual seg 
    18531813 */ 
    18541814 
    18551815int elf_data_start(Symbol *sdata, targ_size_t datasize, int seg) 
    18561816{ 
    18571817    targ_size_t alignbytes; 
     
    19851944    return symidx; 
    19861945} 
    19871946 
    19881947int objextdef(const char *name) 
    19891948{ 
    19901949    return objextern(name); 
    19911950} 
    19921951 
    19931952/******************************* 
    19941953 * Output an external for existing symbol. 
    19951954 * Input: 
    19961955 *      s       Symbol to do EXTDEF on 
    19971956 *              (Name is to be mangled) 
    19981957 * Returns: 
    19991958 *      Symbol table index of the definition 
    20001959 *      NOTE: Numbers will not be linear. 
    20011960 */ 
    20021961 
    20031962int objextern(Symbol *s) 
    20041963{ 
    2005     IDXSTR namidx; 
    20061964    int symtype,sectype; 
    2007     targ_size_t size; 
     1965    unsigned size; 
    20081966 
    20091967    //dbg_printf("objextern('%s') %x\n",s->Sident,s->Svalue); 
    20101968    symbol_debug(s); 
    2011     namidx = elf_addmangled(s); 
     1969    IDXSTR namidx = elf_addmangled(s); 
    20121970 
    20131971#if SCPP 
    20141972    if (s->Sscope && !tyfunc(s->ty())) 
    20151973    { 
    20161974        symtype = STT_OBJECT; 
    20171975        sectype = SHT_COMMON; 
    20181976        size = type_size(s->Stype); 
    20191977    } 
    20201978    else 
    20211979#endif 
    20221980    { 
    20231981        symtype = STT_NOTYPE; 
    20241982        sectype = SHT_UNDEF; 
    20251983        size = 0; 
    20261984    } 
    20271985    if (s->ty() & mTYthread) 
    20281986    { 
    20291987        //printf("objextern('%s') %x TLS\n",s->Sident,s->Svalue); 
    20301988        symtype = STT_TLS; 
    20311989    } 
     
    20341992        /*(s->ty() & mTYweak) ? STB_WEAK : */STB_GLOBAL, sectype); 
    20351993    return s->Sxtrnnum; 
    20361994 
    20371995} 
    20381996 
    20391997/******************************* 
    20401998 * Output a common block definition. 
    20411999 * Input: 
    20422000 *      p ->    external identifier 
    20432001 *      size    size in bytes of each elem 
    20442002 *      count   number of elems 
    20452003 * Returns: 
    20462004 *      Symbol table index for symbol 
    20472005 */ 
    20482006 
    20492007int obj_comdef(Symbol *s,targ_size_t size,targ_size_t count) 
    20502008{ 
    20512009    //printf("obj_comdef('%s',%d,%d)\n",s->Sident,size,count); 
    20522010    symbol_debug(s); 
    20532011 
     2012    int align = I64 ? 16 : 4; 
    20542013    if (s->ty() & mTYthread) 
    20552014    { 
    20562015        s->Sseg = elf_getsegment(".tbss.", cpp_mangle(s), 
    2057                 SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
     2016                SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, align); 
    20582017        s->Sfl = FLtlsdata; 
    20592018        SegData[s->Sseg]->SDsym = s; 
    20602019        SegData[s->Sseg]->SDoffset += size * count; 
    20612020        objpubdef(s->Sseg, s, 0); 
    20622021        searchfixlist(s); 
    20632022        return s->Sseg; 
    20642023    } 
    20652024    else 
    20662025    { 
    20672026        s->Sseg = elf_getsegment(".bss.", cpp_mangle(s), 
    2068                 SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4); 
     2027                SHT_NOBITS, SHF_ALLOC|SHF_WRITE, align); 
    20692028        s->Sfl = FLudata; 
    20702029        SegData[s->Sseg]->SDsym = s; 
    20712030        SegData[s->Sseg]->SDoffset += size * count; 
    20722031        objpubdef(s->Sseg, s, 0); 
    20732032        searchfixlist(s); 
    20742033        return s->Sseg; 
    20752034    } 
    20762035#if 0 
    20772036    IDXSTR namidx = elf_addmangled(s); 
    20782037    alignOffset(UDATA,size); 
    20792038    IDXSYM symidx = elf_addsym(namidx, SegData[UDATA]->SDoffset, size*count, 
    20802039                    (s->ty() & mTYthread) ? STT_TLS : STT_OBJECT, 
    20812040                    STB_WEAK, SHI_BSS); 
    20822041    //dbg_printf("\tobj_comdef returning symidx %d\n",symidx); 
    20832042    s->Sseg = UDATA; 
    20842043    s->Sfl = FLudata; 
    20852044    SegData[UDATA]->SDoffset += size * count; 
    20862045    return symidx; 
    20872046#endif 
    20882047} 
     
    23452304 *              reftodatseg(DATA,offset,3 * sizeof(int *),UDATA); 
    23462305 */ 
    23472306 
    23482307void reftodatseg(int seg,targ_size_t offset,targ_size_t val, 
    23492308        unsigned targetdatum,int flags) 
    23502309{ 
    23512310    Outbuffer *buf; 
    23522311    int save; 
    23532312 
    23542313    buf = SegData[seg]->SDbuf; 
    23552314    save = buf->size(); 
    23562315    buf->setsize(offset); 
    23572316    //dbg_printf("reftodatseg(seg=%d, offset=x%lx, val=x%lx,data %x, flags %x )\n", 
    23582317    //  seg,offset,val,targetdatum,flags); 
    23592318    /*if (OPT_IS_SET(OPTfwritable_strings)) 
    23602319    { 
    23612320        elf_addrel(seg,offset,RI_TYPE_SYM32,STI_DATA,0); 
    23622321    } 
    23632322    else*/ 
    23642323    { 
    2365         unsigned type = RI_TYPE_SYM32; 
    2366  
    2367         if (MAP_SEG2TYP(seg) == CODE && config.flags3 & CFG3pic) 
    2368             type = RI_TYPE_GOTOFF; 
    2369         else if (MAP_SEG2SEC(targetdatum)->sh_flags & SHF_TLS) 
    2370             type = config.flags3 & CFG3pic ? RI_TYPE_TLS_GD : RI_TYPE_TLS_LE; 
    2371  
    2372         elf_addrel(seg,offset,type,STI_RODAT,0); 
    2373     } 
    2374     if (I64) 
    2375         buf->write64(val); 
    2376     else 
    2377         buf->write32(val); 
    2378     if (save > offset + NPTRSIZE) 
     2324        int relinfo; 
     2325 
     2326        if (I64) 
     2327        { 
     2328            if (MAP_SEG2TYP(seg) == CODE && config.flags3 & CFG3pic) 
     2329                relinfo = R_X86_64_PC32; 
     2330            else if (MAP_SEG2SEC(targetdatum)->sh_flags & SHF_TLS) 
     2331                relinfo = config.flags3 & CFG3pic ? R_X86_64_TLSGD : R_X86_64_TPOFF32; 
     2332            else 
     2333                relinfo = R_X86_64_32; 
     2334        } 
     2335        else 
     2336        { 
     2337            if (MAP_SEG2TYP(seg) == CODE && config.flags3 & CFG3pic) 
     2338                relinfo = RI_TYPE_GOTOFF; 
     2339            else if (MAP_SEG2SEC(targetdatum)->sh_flags & SHF_TLS) 
     2340                relinfo = config.flags3 & CFG3pic ? RI_TYPE_TLS_GD : RI_TYPE_TLS_LE; 
     2341            else 
     2342                relinfo = RI_TYPE_SYM32; 
     2343        } 
     2344 
     2345        elf_addrel(seg, offset, relinfo, STI_RODAT, 0); 
     2346    } 
     2347    buf->write32(val); 
     2348    if (save > offset + 4) 
    23792349        buf->setsize(save); 
    23802350} 
    23812351 
    23822352/******************************* 
    23832353 * Refer to address that is in the code segment. 
    23842354 * Only offsets are output, regardless of the memory model. 
    23852355 * Used to put values in switch address tables. 
    23862356 * Input: 
    23872357 *      seg =           where the address is going (CODE or DATA) 
    23882358 *      offset =        offset within seg 
    23892359 *      val =           displacement from start of this module 
    23902360 */ 
    23912361 
    23922362void reftocodseg(int seg,targ_size_t offset,targ_size_t val) 
    23932363{ 
    23942364    Outbuffer *buf; 
    23952365    int save; 
    23962366    int segtyp = MAP_SEG2TYP(seg); 
    23972367 
    23982368    //dbg_printf("reftocodseg(seg=%d, offset=x%lx, val=x%lx )\n",seg,offset,val); 
    23992369    assert(seg > 0);            // COMDATs not done yet 
    24002370    buf = SegData[seg]->SDbuf; 
    24012371    save = buf->size(); 
    24022372    buf->setsize(offset); 
    24032373#if 0 
    24042374    if (segtyp == CODE) 
    24052375    { 
    24062376        val = val - funcsym_p->Soffset; 
    24072377        elf_addrel(seg,offset,RI_TYPE_PC32,funcsym_p->Sxtrnnum,0); 
    24082378    } 
    24092379    else 
    24102380#endif 
    24112381    { 
    24122382        val = val - funcsym_p->Soffset; 
    2413         elf_addrel(seg,offset, 
    2414                 (config.flags3 & CFG3pic) ? RI_TYPE_GOTOFF : RI_TYPE_SYM32, 
    2415                 funcsym_p->Sxtrnnum,0)
    2416     } 
    2417     if (I64) 
    2418         buf->write64(val); 
    2419     else 
    2420         buf->write32(val); 
    2421     if (save > offset + NPTRSIZE
     2383        int relinfo; 
     2384        if (I64) 
     2385            relinfo = (config.flags3 & CFG3pic) ? R_X86_64_PC32 : R_X86_64_32
     2386        else 
     2387            relinfo = (config.flags3 & CFG3pic) ? RI_TYPE_GOTOFF : RI_TYPE_SYM32; 
     2388        elf_addrel(seg,offset, relinfo, funcsym_p->Sxtrnnum, 0); 
     2389    } 
     2390    buf->write32(val); 
     2391    if (save > offset + 4
    24222392        buf->setsize(save); 
    24232393} 
    24242394 
    24252395/******************************* 
    24262396 * Refer to an identifier. 
    24272397 * Input: 
    24282398 *      segtyp =        where the address is going (CODE or DATA) 
    24292399 *      offset =        offset within seg 
    24302400 *      s ->            Symbol table entry for identifier 
    24312401 *      val =           displacement from identifier 
    24322402 *      flags =         CFselfrel: self-relative 
    24332403 *                      CFseg: get segment 
    24342404 *                      CFoff: get offset 
     2405 *                      CFoffset64: 64 bit fixup 
    24352406 * Returns: 
    2436  *      number of bytes in reference (2 or 4 or 8) 
     2407 *      number of bytes in reference (4 or 8) 
    24372408 */ 
    24382409 
    24392410int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, 
    24402411        int flags) 
    24412412{ 
    24422413    tym_t ty; 
    24432414    bool external = TRUE; 
    24442415    Outbuffer *buf; 
    24452416    elf_u32_f32 relinfo,refseg; 
    24462417    int segtyp = MAP_SEG2TYP(seg); 
    24472418    //assert(val == 0); 
     2419    int retsize = (flags & CFoffset64) ? 8 : 4; 
    24482420 
    24492421#if 0 
    24502422    dbg_printf("\nreftoident('%s' seg %d, offset x%lx, val x%lx, flags x%x)\n", 
    24512423        s->Sident,seg,offset,val,flags); 
    24522424    dbg_printf("Sseg = %d, Sxtrnnum = %d\n",s->Sseg,s->Sxtrnnum); 
    24532425    symbol_print(s); 
    24542426#endif 
    24552427 
    24562428    ty = s->ty(); 
    24572429    if (s->Sxtrnnum) 
    24582430    {                           // identifier is defined somewhere else 
    24592431        if (I64) 
    24602432        { 
    24612433            if (SymbolTable64[s->Sxtrnnum].st_shndx != SHT_UNDEF) 
    24622434                external = FALSE; 
    24632435        } 
    24642436        else 
    24652437        { 
    24662438            if (SymbolTable[s->Sxtrnnum].st_shndx != SHT_UNDEF) 
    24672439                external = FALSE; 
    24682440        } 
    24692441    } 
    24702442 
    24712443    switch (s->Sclass) 
    24722444    { 
    24732445        case SClocstat: 
    24742446            buf = SegData[seg]->SDbuf; 
    2475             refseg = /*(OPT_IS_SET(OPTfwritable_strings)) ? 
    2476                 STI_DATA : */STI_RODAT; 
    2477             relinfo = config.flags3 & CFG3pic ? 
    2478                   RI_TYPE_GOTOFF:RI_TYPE_SYM32,STI_RODAT; 
    2479             if (s->Sfl == FLtlsdata) 
    2480                 relinfo = config.flags3 & CFG3pic ? RI_TYPE_TLS_GD : RI_TYPE_TLS_LE; 
    2481             elf_addrel(seg,offset,relinfo,refseg,0); 
    24822447            if (I64) 
     2448            { 
     2449                if (s->Sfl == FLtlsdata) 
     2450                    relinfo = config.flags3 & CFG3pic ? R_X86_64_TLSGD : R_X86_64_TPOFF32; 
     2451                else 
     2452                    relinfo = config.flags3 & CFG3pic ? R_X86_64_PC32 : R_X86_64_32; 
     2453            } 
     2454            else 
     2455            { 
     2456                if (s->Sfl == FLtlsdata) 
     2457                    relinfo = config.flags3 & CFG3pic ? RI_TYPE_TLS_GD : RI_TYPE_TLS_LE; 
     2458                else 
     2459                    relinfo = config.flags3 & CFG3pic ? RI_TYPE_GOTOFF : RI_TYPE_SYM32; 
     2460            } 
     2461            if (flags & CFoffset64 && relinfo == R_X86_64_32) 
     2462            { 
     2463                relinfo = R_X86_64_64; 
     2464            } 
     2465            elf_addrel(seg,offset,relinfo,STI_RODAT,0); 
     2466            if (retsize == 8) 
    24832467                buf->write64(val + s->Soffset); 
    24842468            else 
    24852469                buf->write32(val + s->Soffset); 
    24862470            break; 
    24872471 
    24882472        case SCcomdat: 
    24892473        case_SCcomdat: 
    24902474        case SCstatic: 
    24912475#if 0 
    24922476            if ((s->Sflags & SFLthunk) && s->Soffset) 
    24932477            {                   // A thunk symbol that has be defined 
    24942478                assert(s->Sseg == seg); 
    24952479                val = (s->Soffset+val) - (offset+4); 
    24962480                goto outaddrval; 
    24972481            } 
    24982482            // FALL_THROUGH 
    24992483#endif 
    25002484 
    25012485        case SCextern: 
    25022486        case SCcomdef: 
    25032487        case_extern: 
    25042488        case SCglobal: 
    25052489            if (!s->Sxtrnnum) 
    25062490            {   // not in symbol table yet - class might change 
    25072491                //dbg_printf("\tadding %s to fixlist\n",s->Sident); 
    25082492                addtofixlist(s,offset,seg,val,flags); 
    2509                 return NPTRSIZE
     2493                return retsize
    25102494            } 
    25112495            else 
    25122496            { 
    25132497                int save; 
    25142498                buf = SegData[seg]->SDbuf; 
    25152499                save = buf->size(); 
    25162500                buf->setsize(offset); 
    25172501                if (flags & CFselfrel) 
    25182502                {               // only for function references within code segments 
    25192503                    if (!external &&            // local definition found 
    25202504                         s->Sseg == seg &&      // within same code segment 
    25212505                          (!(config.flags3 & CFG3pic) ||        // not position indp code 
    25222506                           s->Sclass == SCstatic)) // or is pic, but declared static 
    25232507                    {                   // Can use PC relative 
    25242508                        //dbg_printf("\tdoing PC relative\n"); 
    2525                         val = (s->Soffset+val) - (offset+NPTRSIZE); 
     2509                        val = (s->Soffset+val) - (offset+4); 
    25262510                    } 
    25272511                    else 
    25282512                    { 
    2529                         val = (targ_size_t)-NPTRSIZE
     2513                        val = (targ_size_t)-4
    25302514                        //dbg_printf("\tadding relocation\n"); 
     2515                        if (I64) 
     2516                            relinfo = config.flags3 & CFG3pic ?  R_X86_64_PLT32 : R_X86_64_PC32; 
     2517                        else 
     2518                            relinfo = config.flags3 & CFG3pic ?  RI_TYPE_PLT32 : RI_TYPE_PC32; 
    25312519                        elf_addrel(seg,offset, 
    2532                                 config.flags3 & CFG3pic ?  RI_TYPE_PLT32 : RI_TYPE_PC32
     2520                                relinfo
    25332521                                s->Sxtrnnum,0); 
    25342522                    } 
    25352523                } 
    25362524                else 
    25372525                {       // code to code code to data, data to code, data to data refs 
    25382526                    refseg = s->Sxtrnnum;       // default to name symbol table entry 
    25392527                    if (s->Sclass == SCstatic) 
    25402528                    {                           // offset into .data or .bss seg 
    25412529                        refseg = MAP_SEG2SYMIDX(s->Sseg); 
    25422530                                                // use segment symbol table entry 
    25432531                        val += s->Soffset; 
    25442532                        if (!(config.flags3 & CFG3pic) ||       // all static refs from normal code 
    25452533                             segtyp == DATA)    // or refs from data from posi indp 
    25462534                        { 
    2547                            relinfo = RI_TYPE_SYM32; 
     2535                           relinfo = I64 ? R_X86_64_32 : RI_TYPE_SYM32; 
    25482536                        } 
    25492537                        else 
    25502538                        { 
    2551                             relinfo = RI_TYPE_GOTOFF; 
     2539                            relinfo = I64 ? R_X86_64_PC32 : RI_TYPE_GOTOFF; 
    25522540                        } 
    25532541                    } 
    25542542                    else if (config.flags3 & CFG3pic && s == GOTsym) 
    25552543                    {                   // relocation for Gbl Offset Tab 
    2556                         relinfo =  RI_TYPE_GOTPC; 
     2544                        relinfo =  I64 ? R_X86_64_NONE : RI_TYPE_GOTPC; 
    25572545                    } 
    25582546                    else if (segtyp == DATA) 
    2559                     {                   // relocation from with in DATA seg 
    2560                         relinfo = RI_TYPE_SYM32; 
     2547                    {                   // relocation from within DATA seg 
     2548                        relinfo = I64 ? R_X86_64_32 : RI_TYPE_SYM32; 
    25612549                    } 
    25622550                    else 
    2563                     {                   // relocation from with in CODE seg 
    2564                         relinfo = config.flags3 & CFG3pic ? 
    2565                              RI_TYPE_GOT32 : RI_TYPE_SYM32; 
     2551                    {                   // relocation from within CODE seg 
     2552                        if (I64) 
     2553                            relinfo = config.flags3 & CFG3pic ? R_X86_64_NONE : R_X86_64_32; 
     2554                        else 
     2555                            relinfo = config.flags3 & CFG3pic ? RI_TYPE_GOT32 : RI_TYPE_SYM32; 
    25662556                    } 
    25672557                    if ((s->ty() & mTYLINK) & mTYthread) 
    25682558                    { 
    2569                         if (config.flags3 & CFG3pic
     2559                        if (I64
    25702560                        { 
    2571                             if (s->Sclass == SCstatic) 
    2572                                 relinfo = RI_TYPE_TLS_LE;  // TLS_GD? 
     2561                            if (config.flags3 & CFG3pic) 
     2562                            { 
     2563                                if (s->Sclass == SCstatic) 
     2564                                    relinfo = R_X86_64_TPOFF32;  // TLS_GD? 
     2565                                else 
     2566                                    relinfo = R_X86_64_GOTTPOFF; 
     2567                            } 
    25732568                            else 
    2574                                 relinfo = RI_TYPE_TLS_IE; 
     2569                            { 
     2570                                if (s->Sclass == SCstatic) 
     2571                                    relinfo = R_X86_64_TPOFF32; 
     2572                                else 
     2573                                    relinfo = R_X86_64_GOTTPOFF; 
     2574                            } 
    25752575                        } 
    25762576                        else 
    25772577                        { 
    2578                             if (s->Sclass == SCstatic) 
    2579                                 relinfo = RI_TYPE_TLS_LE; 
     2578                            if (config.flags3 & CFG3pic) 
     2579                            { 
     2580                                if (s->Sclass == SCstatic) 
     2581                                    relinfo = RI_TYPE_TLS_LE;  // TLS_GD? 
     2582                                else 
     2583                                    relinfo = RI_TYPE_TLS_IE; 
     2584                            } 
    25802585                            else 
    2581                                 relinfo = RI_TYPE_TLS_IE; 
     2586                            { 
     2587                                if (s->Sclass == SCstatic) 
     2588                                    relinfo = RI_TYPE_TLS_LE; 
     2589                                else 
     2590                                    relinfo = RI_TYPE_TLS_IE; 
     2591                            } 
    25822592                        } 
     2593                    } 
     2594                    if (flags & CFoffset64 && relinfo == R_X86_64_32) 
     2595                    { 
     2596                        relinfo = R_X86_64_64; 
    25832597                    } 
    25842598                    //printf("\t\t************* adding relocation\n"); 
    25852599                    elf_addrel(seg,offset,relinfo,refseg,0); 
    25862600                } 
    25872601outaddrval: 
    2588                 if (I64
     2602                if (retsize == 8
    25892603                    buf->write64(val); 
    25902604                else 
    25912605                    buf->write32(val); 
    2592                 if (save > offset + NPTRSIZE
     2606                if (save > offset + retsize
    25932607                    buf->setsize(save); 
    25942608            } 
    25952609            break; 
    25962610 
    25972611        case SCsinline: 
    25982612        case SCeinline: 
    25992613            printf ("Undefined inline value <<fixme>>\n"); 
    26002614            //warerr(WM_undefined_inline,s->Sident); 
    26012615        case SCinline: 
    26022616            if (tyfunc(ty)) 
    26032617            { 
    26042618                s->Sclass = SCextern; 
    26052619                goto case_extern; 
    26062620            } 
    26072621            else if (config.flags2 & CFG2comdat) 
    26082622                goto case_SCcomdat;     // treat as initialized common block 
    26092623 
    26102624        default: 
    26112625#ifdef DEBUG 
    26122626            //symbol_print(s); 
    26132627#endif 
    26142628            assert(0); 
    26152629    } 
    2616     return NPTRSIZE
     2630    return retsize
    26172631} 
    26182632 
    26192633/***************************************** 
    26202634 * Generate far16 thunk. 
    26212635 * Input: 
    26222636 *      s       Symbol to generate a thunk for 
    26232637 */ 
    26242638 
    26252639void obj_far16thunk(Symbol *s) 
    26262640{ 
    26272641    //dbg_printf("obj_far16thunk('%s')\n", s->Sident); 
    26282642    assert(0); 
    26292643} 
    26302644 
    26312645/************************************** 
    26322646 * Mark object file as using floating point. 
    26332647 */ 
    26342648 
    26352649void obj_fltused() 
    26362650{ 
    26372651    //dbg_printf("obj_fltused()\n"); 
    2638 } 
    2639  
    2640 static int obj_align(Symbol *s) 
    2641 { 
    2642     if (type_size(s->Stype) == CHARSIZE) 
    2643         return 1; 
    2644     else if (type_size(s->Stype) == SHORTSIZE) 
    2645         return 2; 
    2646     else if (type_size(s->Stype) == LONGSIZE) 
    2647         return 4; 
    2648     else 
    2649         return I64 ? 8 : 4; 
    26502652} 
    26512653 
    26522654/************************************ 
    26532655 * Close and delete .OBJ file. 
    26542656 */ 
    26552657 
    26562658void objfile_delete() 
    26572659{ 
    26582660    //remove(fobjname); // delete corrupt output file 
    26592661} 
    26602662 
    26612663/********************************** 
    26622664 * Terminate. 
    26632665 */ 
    26642666 
    26652667void objfile_term() 
    26662668{ 
    26672669#if TERMCODE 
    26682670    mem_free(fobjname); 
    26692671    fobjname = NULL; 
     
    26992701            offset = (foffset + 31) & ~31; 
    27002702            break; 
    27012703        default: 
    27022704            dbg_printf("size was %d\n",(int)size); 
    27032705            assert(0); 
    27042706            break; 
    27052707    } 
    27062708    if (offset > foffset) 
    27072709        fobjbuf->writezeros(offset - foffset); 
    27082710    return offset; 
    27092711} 
    27102712 
    27112713/*************************************** 
    27122714 * Stuff pointer to ModuleInfo in its own segment. 
    27132715 */ 
    27142716 
    27152717#if MARS 
    27162718 
    27172719void obj_moduleinfo(Symbol *scc) 
    27182720{ 
    2719     int offset, codeOffset, refOffset; 
    2720     Outbuffer *buf; 
    2721     int seg; 
    2722  
    2723     /* Put in the ModuleInfo reference for some reason. */ 
    2724     /*{ 
    2725         seg = DATA; 
    2726         offset = SegData[seg]->SDoffset; 
    2727         SegData[seg]->SDoffset += reftoident(seg, offset, scc, 0, CFoff); 
    2728     }*/ 
     2721    int codeOffset, refOffset; 
    27292722 
    27302723    /* Put in the ModuleReference. */ 
    27312724    { 
    27322725        /* struct ModuleReference 
    27332726         * { 
    27342727         *      void*   next; 
    27352728         *      ModuleReference* module; 
    27362729         * } 
    27372730         */ 
    2738         seg = DATA; 
     2731        const int seg = DATA; 
     2732        alignOffset(seg, NPTRSIZE); 
    27392733        SegData[seg]->SDoffset = SegData[seg]->SDbuf->size(); 
    27402734        refOffset = SegData[seg]->SDoffset; 
    27412735        SegData[seg]->SDbuf->writezeros(NPTRSIZE); 
    27422736        SegData[seg]->SDoffset += NPTRSIZE; 
    27432737        SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoff); 
    2744     } 
    2745  
    2746     /* Constructor that links the ModuleReference into the code. */ 
     2738        alignOffset(seg, NPTRSIZE); 
     2739    } 
     2740 
     2741    /* Constructor that links the ModuleReference to the head of 
     2742     * the list pointed to by _Dmoduleref 
     2743     */ 
    27472744    { 
    27482745        /*      ret 
     2746         * codeOffset: 
    27492747         *      pushad 
    27502748         *      mov     EAX,&ModuleReference 
    27512749         *      mov     ECX,_DmoduleRef 
    27522750         *      mov     EDX,[ECX] 
    27532751         *      mov     [EAX],EDX 
    27542752         *      mov     [ECX],EAX 
    27552753         *      popad 
    27562754         *      ret 
    27572755         */ 
    27582756 
    2759         seg = CODE; 
    2760         buf = SegData[seg]->SDbuf; 
     2757        const int reltype = I64 ? R_X86_64_32 : RI_TYPE_SYM32; 
     2758        const int refsize = 4;                          // use 32 bit relocations, even in 64 bit mode 
     2759 
     2760        const int seg = CODE; 
     2761        Outbuffer *buf = SegData[seg]->SDbuf; 
    27612762        SegData[seg]->SDoffset = buf->size(); 
    27622763        codeOffset = SegData[seg]->SDoffset + 1; 
    2763 //      codeOffset = SegData[seg]->SDoffset; 
    27642764        buf->writeByte(0xC3); /* ret */ 
    27652765 
    27662766        buf->writeByte(0x60); /* pushad */ 
    27672767 
    27682768        /* movl ModuleReference*, %eax */ 
    27692769        buf->writeByte(0xB8); 
    27702770        buf->write32(refOffset); 
    2771         elf_addrel(seg, codeOffset + 2, RI_TYPE_SYM32, STI_DATA, 0); 
     2771        elf_addrel(seg, codeOffset + 2, reltype, STI_DATA, 0); 
    27722772 
    27732773        /* movl _Dmodule_ref, %ecx */ 
    27742774        buf->writeByte(0xB9); 
    2775         buf->write32(0);//offset); 
    2776         elf_addrel(seg, codeOffset + 7, RI_TYPE_SYM32, objextern("_Dmodule_ref"), 0); 
     2775        buf->write32(0); 
     2776        elf_addrel(seg, codeOffset + 7, reltype, objextern("_Dmodule_ref"), 0); 
    27772777 
    27782778        buf->writeByte(0x8B); buf->writeByte(0x11); /* movl (%ecx), %edx */ 
    27792779        buf->writeByte(0x89); buf->writeByte(0x10); /* movl %edx, (%eax) */ 
    27802780        buf->writeByte(0x89); buf->writeByte(0x01); /* movl %eax, (%ecx) */ 
    27812781 
    27822782        buf->writeByte(0x61); /* popad */ 
    27832783        buf->writeByte(0xC3); /* ret */ 
    27842784        SegData[seg]->SDoffset = buf->size(); 
    27852785    } 
    27862786 
    2787     /* Create the linked list-generating code. */ 
    2788     seg = elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE,4); 
    2789  
    2790     buf = SegData[seg]->SDbuf; 
     2787    /* Add reference to constructor into ".ctors" segment 
     2788     */ 
     2789    const int seg = elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, NPTRSIZE); 
     2790 
     2791    Outbuffer *buf = SegData[seg]->SDbuf; 
    27912792    buf->write32(codeOffset); 
    2792     elf_addrel(seg, SegData[seg]->SDoffset, RI_TYPE_SYM32, STI_TEXT, 0); 
     2793    elf_addrel(seg, SegData[seg]->SDoffset, I64 ? R_X86_64_64 : RI_TYPE_SYM32, STI_TEXT, 0); 
    27932794    SegData[seg]->SDoffset += NPTRSIZE; 
    27942795} 
    27952796 
    27962797#endif 
    2797  
    2798 /************************************ 
    2799  * Output long word of data. 
    2800  * Input: 
    2801  *      seg     CODE, DATA, CDATA, UDATA 
    2802  *      offset  offset of start of data 
    2803  *      data    long word of data 
    2804  *   Present only if size == 2: 
    2805  *      lcfd    LCxxxx | FDxxxx 
    2806  *      if (FD_F2 | FD_T6) 
    2807  *              idx1 = external Symbol # 
    2808  *      else 
    2809  *              idx1 = frame datum 
    2810  *              idx2 = target datum 
    2811  */ 
    2812  
    2813 void obj_long(int seg,targ_size_t offset,unsigned long data, 
    2814         unsigned lcfd,unsigned idx1,unsigned idx2) 
    2815 { 
    2816     printf ("obj_long\n"); 
    2817     exit (1); 
    2818     /* 
    2819     unsigned i; 
    2820  
    2821     if ( 
    2822         (seg != obj.ledata->lseg ||             // or segments don't match 
    2823          obj.ledata->i + tysize[TYfptr] > LEDATAMAX || // or it'll overflow 
    2824          offset < obj.ledata->offset || // underflow 
    2825          offset > obj.ledata->offset + obj.ledata->i 
    2826         ) 
    2827      ) 
    2828         ledata_new(seg,offset); 
    2829   i = offset - obj.ledata->offset; 
    2830   if (obj.ledata->i < i + tysize[TYfptr]) 
    2831         obj.ledata->i = i + tysize[TYfptr]; 
    2832   TOLONG(obj.ledata->data + i,data); 
    2833   if (I32)                              // if 6 byte far pointers 
    2834         TOWORD(obj.ledata->data + i + LONGSIZE,0);              // fill out seg 
    2835   addfixup(offset - obj.ledata->offset,lcfd,idx1,idx2); 
    2836   */ 
    2837 } 
    28382798 
    28392799/************************************* 
    28402800 */ 
    28412801 
    28422802void elfobj_gotref(symbol *s) 
    28432803{ 
    28442804    //printf("elfobj_gotref(%x '%s', %d)\n",s,s->Sident, s->Sclass); 
    28452805    switch(s->Sclass) 
    28462806    { 
    28472807        case SCstatic: 
    28482808        case SClocstat: 
    28492809            s->Sfl = FLgotoff; 
    28502810            break; 
    28512811 
    28522812        case SCextern: 
    28532813        case SCglobal: 
    28542814        case SCcomdat: 
    28552815        case SCcomdef: 
    28562816            s->Sfl = FLgot; 
    28572817            break; 
  • branches/dmd-1.x/src/backend/iasm.h

    r428 r572  
    11 
    22/* 
    33 * Copyright (c) 1992-1999 by Symantec 
    4  * Copyright (c) 1999-2008 by Digital Mars 
     4 * Copyright (c) 1999-2010 by Digital Mars 
    55 * All Rights Reserved 
    66 * http://www.digitalmars.com 
    77 * Written by Mike Cote, John Micco and Walter Bright 
    88 * 
    99 * This source file is made available for personal use 
    1010 * only. The license is in /dmd/src/dmd/backendlicense.txt 
    1111 * or /dm/src/dmd/backendlicense.txt 
    1212 * For any other uses, please contact Digital Mars. 
    1313 */ 
    1414 
    1515#include <setjmp.h> 
    1616 
    1717///////////////////////////////////////////////// 
    1818// Instruction flags (usFlags) 
    1919// 
    2020// 
    2121 
    2222// This is for when the reg field of modregrm specifies which instruction it is 
    2323#define NUM_MASK        0x7 
    2424#define _0      (0x0 | _modrm)          // insure that some _modrm bit is set 
     
    2828#define _4      0x4 
    2929#define _5      0x5 
    3030#define _6      0x6 
    3131#define _7      0x7 
    3232 
    3333#define _modrm  0x10 
    3434 
    3535#define _r      _modrm 
    3636#define _cb     _modrm 
    3737#define _cw     _modrm 
    3838#define _cd     _modrm 
    3939#define _cp     _modrm 
    4040#define _ib     0 
    4141#define _iw     0 
    4242#define _id     0 
    4343#define _rb     0 
    4444#define _rw     0 
    4545#define _rd     0 
    4646#define _16_bit 0x20 
    4747#define _32_bit 0x40 
     48#define _64_bit 0x10000 
    4849#define _I386   0x80            // opcode is only for 386 and later 
    4950#define _16_bit_addr    0x100 
    5051#define _32_bit_addr    0x200 
    5152#define _fwait 0x400    // Add an FWAIT prior to the instruction opcode 
    5253#define _nfwait 0x800   // Do not add an FWAIT prior to the instruction 
    5354 
    5455#define MOD_MASK        0xF000  // Mod mask 
    5556#define _modsi          0x1000  // Instruction modifies SI 
    5657#define _moddx          0x2000  // Instruction modifies DX 
    5758#define _mod2           0x3000  // Instruction modifies second operand 
    5859#define _modax          0x4000  // Instruction modifies AX 
    5960#define _modnot1        0x5000  // Instruction does not modify first operand 
    6061#define _modaxdx        0x6000  // instruction modifies AX and DX 
    6162#define _moddi          0x7000  // Instruction modifies DI 
    6263#define _modsidi        0x8000  // Instruction modifies SI and DI 
    6364#define _modcx          0x9000  // Instruction modifies CX 
    6465#define _modes          0xa000  // Instruction modifies ES 
    6566#define _modall         0xb000  // Instruction modifies all register values 
    6667#define _modsiax        0xc000  // Instruction modifies AX and SI 
    6768#define _modsinot1      0xd000  // Instruction modifies SI and not first param 
    6869 
    6970///////////////////////////////////////////////// 
    7071// Operand flags - usOp1, usOp2, usOp3 
    7172// 
    7273 
    73 typedef unsigned short opflag_t; 
     74typedef unsigned opflag_t; 
    7475 
    7576// Operand flags for normal opcodes 
    7677 
    7778#define _r8     CONSTRUCT_FLAGS( _8, _reg, _normal, 0 ) 
    7879#define _r16    CONSTRUCT_FLAGS(_16, _reg, _normal, 0 ) 
    7980#define _r32    CONSTRUCT_FLAGS(_32, _reg, _normal, 0 ) 
     81#define _r64    CONSTRUCT_FLAGS(_64, _reg, _normal, 0 ) 
    8082#define _m8     CONSTRUCT_FLAGS(_8, _m, _normal, 0 ) 
    8183#define _m16    CONSTRUCT_FLAGS(_16, _m, _normal, 0 ) 
    8284#define _m32    CONSTRUCT_FLAGS(_32, _m, _normal, 0 ) 
    8385#define _m48    CONSTRUCT_FLAGS( _48, _m, _normal, 0 ) 
    84 #define _m64    CONSTRUCT_FLAGS( _anysize, _m, _normal, 0 ) 
     86#define _m64    CONSTRUCT_FLAGS( _64, _m, _normal, 0 ) 
    8587#define _m128   CONSTRUCT_FLAGS( _anysize, _m, _normal, 0 ) 
    8688#define _rm8    CONSTRUCT_FLAGS(_8, _rm, _normal, 0 ) 
    8789#define _rm16   CONSTRUCT_FLAGS(_16, _rm, _normal, 0 ) 
    8890#define _rm32   CONSTRUCT_FLAGS(_32, _rm, _normal, 0) 
    8991#define _r32m16 CONSTRUCT_FLAGS(_32|_16, _rm, _normal, 0) 
    9092#define _imm8   CONSTRUCT_FLAGS(_8, _imm, _normal, 0 ) 
    9193#define _imm16  CONSTRUCT_FLAGS(_16, _imm, _normal, 0) 
    9294#define _imm32  CONSTRUCT_FLAGS(_32, _imm, _normal, 0) 
    9395#define _rel8   CONSTRUCT_FLAGS(_8, _rel, _normal, 0) 
    9496#define _rel16  CONSTRUCT_FLAGS(_16, _rel, _normal, 0) 
    9597#define _rel32  CONSTRUCT_FLAGS(_32, _rel, _normal, 0) 
    9698#define _p1616  CONSTRUCT_FLAGS(_32, _p, _normal, 0) 
    9799#define _m1616  CONSTRUCT_FLAGS(_32, _mnoi, _normal, 0) 
    98100#define _p1632  CONSTRUCT_FLAGS(_48, _p, _normal, 0 ) 
    99101#define _m1632  CONSTRUCT_FLAGS(_48, _mnoi, _normal, 0) 
    100102#define _special  CONSTRUCT_FLAGS( 0, 0, _rspecial, 0 ) 
    101103#define _seg    CONSTRUCT_FLAGS( 0, 0, _rseg, 0 ) 
    102104#define _a16    CONSTRUCT_FLAGS( 0, 0, _addr16, 0 ) 
    103105#define _a32    CONSTRUCT_FLAGS( 0, 0, _addr32, 0 ) 
    104106#define _f16    CONSTRUCT_FLAGS( 0, 0, _fn16, 0) 
    105107                                                // Near function pointer 
    106108#define _f32    CONSTRUCT_FLAGS( 0, 0, _fn32, 0) 
    107109                                                // Far function pointer 
    108110#define _lbl    CONSTRUCT_FLAGS( 0, 0, _flbl, 0 ) 
    109111                                                // Label (in current function) 
    110112 
    111113#define _mmm32  CONSTRUCT_FLAGS( 0, _m, 0, _32) 
    112 #define _mmm64  CONSTRUCT_FLAGS( 0, _m, 0, _64) 
    113 #define _mmm128 CONSTRUCT_FLAGS( 0, _m, 0, _128) 
     114#define _mmm64  CONSTRUCT_FLAGS( _64, _m, 0, _f64) 
     115#define _mmm128 CONSTRUCT_FLAGS( 0, _m, 0, _f128) 
    114116 
    115117#define _xmm_m32 CONSTRUCT_FLAGS( _32, _m, _rspecial, 0) 
    116118#define _xmm_m64 CONSTRUCT_FLAGS( _anysize, _m, _rspecial, 0) 
    117119#define _xmm_m128 CONSTRUCT_FLAGS( _anysize, _m, _rspecial, 0) 
    118120 
    119121#define _moffs8 (_rel8) 
    120122#define _moffs16 (_rel16 ) 
    121123#define _moffs32 (_rel32 ) 
    122124 
    123125 
    124126//////////////////////////////////////////////////////////////////// 
    125127// Operand flags for floating point opcodes are all just aliases for 
    126128// normal opcode variants and only asm_determine_operator_flags should 
    127129// need to care. 
    128130// 
    129 #define _fm80   CONSTRUCT_FLAGS( 0, _m, 0, _80 ) 
    130 #define _fm64   CONSTRUCT_FLAGS( 0, _m, 0, _64 ) 
    131 #define _fm128  CONSTRUCT_FLAGS( 0, _m, 0, _128 ) 
    132 #define _fanysize (_64 | _80 | _112 | _224
     131#define _fm80   CONSTRUCT_FLAGS( 0, _m, 0, _f80 ) 
     132#define _fm64   CONSTRUCT_FLAGS( 0, _m, 0, _f64 ) 
     133#define _fm128  CONSTRUCT_FLAGS( 0, _m, 0, _f128 ) 
     134#define _fanysize (_f64 | _f80 | _f112
    133135 
    134136#define _float_m CONSTRUCT_FLAGS( _anysize, _float, 0, _fanysize) 
    135137 
    136138#define _st     CONSTRUCT_FLAGS( 0, _float, 0, _rst )   // stack register 0 
    137 #define _m112   CONSTRUCT_FLAGS( 0, _m, 0, _112 ) 
    138 #define _m224   CONSTRUCT_FLAGS( 0, _m, 0, _224 ) 
     139#define _m112   CONSTRUCT_FLAGS( 0, _m, 0, _f112 ) 
     140#define _m224   _m112 
    139141#define _m512   _m224 
    140142#define _sti    CONSTRUCT_FLAGS( 0, _float, 0, _rsti ) 
    141143 
    142144////////////////// FLAGS ///////////////////////////////////// 
    143145 
     146#if 1 
     147// bit size                      5      3     3         7 
     148#define CONSTRUCT_FLAGS( uSizemask, aopty, amod, uRegmask ) \ 
     149    ( (uSizemask) | (aopty) << 5 | (amod) << 8 | (uRegmask) << 11) 
     150 
     151#define ASM_GET_uSizemask(us)   ((us) & 0x1F) 
     152#define ASM_GET_aopty(us)       ((ASM_OPERAND_TYPE)(((us) >> 5) & 7)) 
     153#define ASM_GET_amod(us)        ((ASM_MODIFIERS)(((us) >> 8) & 7)) 
     154#define ASM_GET_uRegmask(us)    (((us) >> 11) & 0x7F) 
     155#else 
    144156#define CONSTRUCT_FLAGS( uSizemask, aopty, amod, uRegmask ) \ 
    145157    ( (uSizemask) | (aopty) << 4 | (amod) << 7 | (uRegmask) << 10) 
    146158 
    147159#define ASM_GET_uSizemask(us)   ((us) & 0x0F) 
    148160#define ASM_GET_aopty(us)       ((ASM_OPERAND_TYPE)(((us) & 0x70) >> 4)) 
    149161#define ASM_GET_amod(us)        ((ASM_MODIFIERS)(((us) & 0x380) >> 7)) 
    150162#define ASM_GET_uRegmask(us)    (((us) & 0xFC00) >> 10) 
    151  
    152  
    153 // For uSizemask (4 bits) 
     163#endif 
     164 
     165// For uSizemask (5 bits) 
    154166#define _8  0x1 
    155167#define _16 0x2 
    156168#define _32 0x4 
    157169#define _48 0x8 
    158 #define _anysize (_8 | _16 | _32 | _48 ) 
     170#define _64 0x10 
     171#define _anysize (_8 | _16 | _32 | _48 | _64 ) 
    159172 
    160173// For aopty (3 bits) 
    161174enum ASM_OPERAND_TYPE { 
    162175    _reg,           // _r8, _r16, _r32 
    163176    _m,             // _m8, _m16, _m32, _m48 
    164177    _imm,           // _imm8, _imm16, _imm32 
    165178    _rel,           // _rel8, _rel16, _rel32 
    166179    _mnoi,          // _m1616, _m1632 
    167180    _p,             // _p1616, _p1632 
    168181    _rm,            // _rm8, _rm16, _rm32 
    169182    _float          // Floating point operand, look at cRegmask for the 
    170183                    // actual size 
    171184}; 
    172185 
    173186// For amod (3 bits) 
    174187enum ASM_MODIFIERS { 
    175188    _normal,        // Normal register value 
    176189    _rseg,          // Segment registers 
    177190    _rspecial,      // Special registers 
    178191    _addr16,        // 16 bit address 
    179192    _addr32,        // 32 bit address 
    180193    _fn16,          // 16 bit function call 
    181194    _fn32,          // 32 bit function call 
    182195    _flbl           // Label 
    183196}; 
    184197 
    185 // For uRegmask (6 bits) 
     198// For uRegmask (7 bits) 
    186199 
    187200// uRegmask flags when aopty == _float 
    188201#define _rst    0x1 
    189202#define _rsti   0x2 
    190 #define _64     0x4 
    191 #define _80     0x8 
    192 #define _128    0x40 
    193 #define _112    0x10 
    194 #define _224    0x20 
     203#define _f64    0x4 
     204#define _f80    0x8 
     205#define _f112   0x10 
     206#define _f128   0x20 
    195207 
    196208// _seg register values (amod == _rseg) 
    197209// 
    198210#define _ds     CONSTRUCT_FLAGS( 0, 0, _rseg, 0x01 ) 
    199211#define _es     CONSTRUCT_FLAGS( 0, 0, _rseg, 0x02 ) 
    200212#define _ss     CONSTRUCT_FLAGS( 0, 0, _rseg, 0x04 ) 
    201213#define _fs     CONSTRUCT_FLAGS( 0, 0, _rseg, 0x08 ) 
    202214#define _gs     CONSTRUCT_FLAGS( 0, 0, _rseg, 0x10 ) 
    203215#define _cs     CONSTRUCT_FLAGS( 0, 0, _rseg, 0x20 ) 
    204216 
    205217// 
    206218// _special register values 
    207219// 
    208220#define _crn    CONSTRUCT_FLAGS( 0, 0, _rspecial, 0x01 ) // CRn register (0,2,3) 
    209221#define _drn    CONSTRUCT_FLAGS( 0, 0, _rspecial, 0x02 ) // DRn register (0-3,6-7) 
    210222#define _trn    CONSTRUCT_FLAGS( 0, 0, _rspecial, 0x04 ) // TRn register (3-7) 
    211223#define _mm     CONSTRUCT_FLAGS( 0, 0, _rspecial, 0x08 ) // MMn register (0-7) 
    212224#define _xmm    CONSTRUCT_FLAGS( 0, 0, _rspecial, 0x10 ) // XMMn register (0-7) 
    213225 
    214226// 
    215227// Default register values 
    216228// 
    217229 
    218230#define _al     CONSTRUCT_FLAGS( 0, 0, _normal, 0x01 )  // AL register 
    219231#define _ax     CONSTRUCT_FLAGS( 0, 0, _normal, 0x02 )  // AX register 
    220232#define _eax    CONSTRUCT_FLAGS( 0, 0, _normal, 0x04 )  // EAX register 
    221233#define _dx     CONSTRUCT_FLAGS( 0, 0, _normal, 0x08 )  // DX register 
    222234#define _cl     CONSTRUCT_FLAGS( 0, 0, _normal, 0x10 )  // CL register 
     235#define _rax    CONSTRUCT_FLAGS( 0, 0, _normal, 0x40 )  // RAX register 
     236 
    223237 
    224238#define _rplus_r        0x20 
    225239#define _plus_r CONSTRUCT_FLAGS( 0, 0, 0, _rplus_r ) 
    226240                // Add the register to the opcode (no mod r/m) 
    227241 
    228242 
    229243 
    230244////////////////////////////////////////////////////////////////// 
    231245 
    232246#define ITprefix        0x10    // special prefix 
    233247#define ITjump          0x20    // jump instructions CALL, Jxx and LOOPxx 
    234248#define ITimmed         0x30    // value of an immediate operand controls 
    235249                                // code generation 
    236250#define ITopt           0x40    // not all operands are required 
    237251#define ITshift         0x50    // rotate and shift instructions 
    238252#define ITfloat         0x60    // floating point coprocessor instructions 
    239253#define ITdata          0x70    // DB, DW, DD, DQ, DT pseudo-ops 
    240254#define ITaddr          0x80    // DA (define addresss) pseudo-op 
    241255#define ITMASK          0xF0 
    242256#define ITSIZE          0x0F    // mask for size 
     
    266280    // Float types 
    267281    OPdf, 
    268282    OPdd, 
    269283    OPde, 
    270284 
    271285    // Deprecated 
    272286    OPdw = OPds, 
    273287    OPdq = OPdl, 
    274288    OPdt = OPde, 
    275289#endif 
    276290}; 
    277291 
    278292 
    279293/* from iasm.c */ 
    280294int asm_state(int iFlags); 
    281295 
    282296void asm_process_fixup( block **ppblockLabels ); 
    283297 
    284298typedef struct _PTRNTAB3 { 
    285299        unsigned usOpcode; 
    286         unsigned short usFlags; 
     300        unsigned usFlags; 
    287301        opflag_t usOp1; 
    288302        opflag_t usOp2; 
    289303        opflag_t usOp3; 
    290304} PTRNTAB3, * PPTRNTAB3, ** PPPTRNTAB3; 
    291305 
    292306typedef struct _PTRNTAB2 { 
    293307        unsigned usOpcode; 
    294         unsigned short usFlags; 
     308        unsigned usFlags; 
    295309        opflag_t usOp1; 
    296310        opflag_t usOp2; 
    297311} PTRNTAB2, * PPTRNTAB2, ** PPPTRNTAB2; 
    298312 
    299313typedef struct _PTRNTAB1 { 
    300314        unsigned usOpcode; 
    301         unsigned short usFlags; 
     315        unsigned usFlags; 
    302316        opflag_t usOp1; 
    303317} PTRNTAB1, * PPTRNTAB1, ** PPPTRNTAB1; 
    304318 
    305319typedef struct _PTRNTAB0 { 
    306320        unsigned usOpcode; 
    307321        #define ASM_END 0xffff          // special opcode meaning end of table 
    308         unsigned short usFlags; 
     322        unsigned usFlags; 
    309323} PTRNTAB0, * PPTRNTAB0, ** PPPTRNTAB0; 
    310324 
    311325typedef union _PTRNTAB { 
    312326        PTRNTAB0        *pptb0; 
    313327        PTRNTAB1        *pptb1; 
    314328        PTRNTAB2        *pptb2; 
    315329        PTRNTAB3        *pptb3; 
    316330} PTRNTAB, * PPTRNTAB, ** PPPTRNTAB; 
    317331 
    318332typedef struct 
    319333{ 
    320334        unsigned char usNumops; 
    321335        PTRNTAB ptb; 
    322336} OP; 
    323337 
  • branches/dmd-1.x/src/backend/machobj.c

    r557 r572  
    23092309    int seg = mach_getsegment("__minfodata", "__DATA", align, S_REGULAR); 
    23102310    //printf("obj_moduleinfo(%s) seg = %d:x%x\n", scc->Sident, seg, Offset(seg)); 
    23112311 
    23122312#if 0 
    23132313    type *t = type_fake(TYint); 
    23142314    t->Tmangle = mTYman_c; 
    23152315    char *p = (char *)malloc(5 + strlen(scc->Sident) + 1); 
    23162316    strcpy(p, "SUPER"); 
    23172317    strcpy(p + 5, scc->Sident); 
    23182318    symbol *s_minfo_beg = symbol_name(p, SCglobal, t); 
    23192319    objpubdef(seg, s_minfo_beg, 0); 
    23202320#endif 
    23212321 
    23222322    SegData[seg]->SDoffset += reftoident(seg, Offset(seg), scc, 0, CFoff); 
    23232323 
    23242324    mach_getsegment("__minfo_end", "__DATA", align, S_COALESCED, 4); 
    23252325} 
    23262326 
    23272327#endif 
    23282328 
    2329 /************************************ 
    2330  * Output long word of data. 
    2331  * Input: 
    2332  *      seg     CODE, DATA, CDATA, UDATA 
    2333  *      offset  offset of start of data 
    2334  *      data    long word of data 
    2335  *   Present only if size == 2: 
    2336  *      lcfd    LCxxxx | FDxxxx 
    2337  *      if (FD_F2 | FD_T6) 
    2338  *              idx1 = external Symbol # 
    2339  *      else 
    2340  *              idx1 = frame datum 
    2341  *              idx2 = target datum 
    2342  */ 
    2343  
    2344 void obj_long(int seg,targ_size_t offset,unsigned long data, 
    2345         unsigned lcfd,unsigned idx1,unsigned idx2) 
    2346 { 
    2347     printf("obj_long\n"); 
    2348     exit(1); 
    2349 } 
    2350  
    23512329/************************************* 
    23522330 */ 
    23532331 
    23542332void elfobj_gotref(symbol *s) 
    23552333{ 
    23562334    //printf("elfobj_gotref(%x '%s', %d)\n",s,s->Sident, s->Sclass); 
    23572335    switch(s->Sclass) 
    23582336    { 
    23592337        case SCstatic: 
    23602338        case SClocstat: 
    23612339            s->Sfl = FLgotoff; 
    23622340            break; 
    23632341 
    23642342        case SCextern: 
    23652343        case SCglobal: 
    23662344        case SCcomdat: 
    23672345        case SCcomdef: 
    23682346            s->Sfl = FLgot; 
    23692347            break; 
    23702348 
  • branches/dmd-1.x/src/backend/melf.h

    r428 r572  
    324324} Elf64_Phdr; 
    325325 
    326326typedef struct { 
    327327    Elf64_Word  st_name; 
    328328    unsigned char st_info; 
    329329    unsigned char st_other; 
    330330    Elf64_Half  st_shndx; 
    331331    Elf64_Addr  st_value; 
    332332    Elf64_Xword st_size; 
    333333} Elf64_Sym; 
    334334 
    335335typedef struct { 
    336336    Elf64_Addr  r_offset; 
    337337    Elf64_Xword r_info; 
    338338        #define ELF64_R_SYM(i) ((Elf64_Word)((i)>>32)) 
    339339        #define ELF64_R_TYPE(i) ((Elf64_Word)(i & 0xFFFFFFFF)) 
    340340        #define ELF64_R_INFO(s,t) ((((Elf64_Xword)(s))<<32)|(Elf64_Word)(t)) 
    341341 
    342342        // X86-64 Relocation types 
    343343 
    344         #define R_X86_64_NONE      0 
    345         #define R_X86_64_64        1 
    346         #define R_X86_64_PC32      2 
    347         #define R_X86_64_GOT32     3 
    348         #define R_X86_64_PLT32     4 
    349         #define R_X86_64_COPY      5 
    350         #define R_X86_64_GLOB_DAT  6 
    351         #define R_X86_64_JUMP_SLOT 7 
    352         #define R_X86_64_RELATIVE  8 
    353         #define R_X86_64_GOTPCREL  9 
    354         #define R_X86_64_32       10 
    355         #define R_X86_64_32S      11 
    356         #define R_X86_64_16       12 
    357         #define R_X86_64_PC16     13 
    358         #define R_X86_64_8        14 
    359         #define R_X86_64_PC8      15 
    360         #define R_X86_64_DTPMOD64 16 
    361         #define R_X86_64_DTPOFF64 17 
    362         #define R_X86_64_TPOFF64  18 
    363         #define R_X86_64_TLSGD    19 
    364         #define R_X86_64_TLSLD    20 
    365         #define R_X86_64_DTPOFF32 21 
    366         #define R_X86_64_GOTTPOFF 22 
    367         #define R_X86_64_TPOFF32  23 
    368         #define R_X86_64_GNU_VTINHERIT 250 
    369         #define R_X86_64_GNU_VTENTRY   251 
     344        #define R_X86_64_NONE      0     // -- No relocation 
     345        #define R_X86_64_64        1     // 64 Direct 64 bit 
     346        #define R_X86_64_PC32      2     // 32 PC relative 32 bit signed 
     347        #define R_X86_64_GOT32     3     // 32 32 bit GOT entry 
     348        #define R_X86_64_PLT32     4     // 32 bit PLT address 
     349        #define R_X86_64_COPY      5     // -- Copy symbol at runtime 
     350        #define R_X86_64_GLOB_DAT  6     // 64 Create GOT entry 
     351        #define R_X86_64_JUMP_SLOT 7     // 64 Create PLT entry 
     352        #define R_X86_64_RELATIVE  8     // 64 Adjust by program base 
     353        #define R_X86_64_GOTPCREL  9     // 32 32 bit signed pc relative offset to GOT 
     354        #define R_X86_64_32       10     // 32 Direct 32 bit zero extended 
     355        #define R_X86_64_32S      11     // 32 Direct 32 bit sign extended 
     356        #define R_X86_64_16       12     // 16 Direct 16 bit zero extended 
     357        #define R_X86_64_PC16     13     // 16 16 bit sign extended pc relative 
     358        #define R_X86_64_8        14     //  8 Direct 8 bit sign extended 
     359        #define R_X86_64_PC8      15     //  8 8 bit sign extended pc relative 
     360        #define R_X86_64_DTPMOD64 16     // 64 ID of module containing symbol 
     361        #define R_X86_64_DTPOFF64 17     // 64 Offset in TLS block 
     362        #define R_X86_64_TPOFF64  18     // 64 Offset in initial TLS block 
     363        #define R_X86_64_TLSGD    19     // 32 PC relative offset to GD GOT block 
     364        #define R_X86_64_TLSLD    20     // 32 PC relative offset to LD GOT block 
     365        #define R_X86_64_DTPOFF32 21     // 32 Offset in TLS block 
     366        #define R_X86_64_GOTTPOFF 22     // 32 PC relative offset to IE GOT entry 
     367        #define R_X86_64_TPOFF32  23     // 32 Offset in initial TLS block 
     368        #define R_X86_64_PC64     24     // 64 
     369        #define R_X86_64_GOTOFF64 25     // 64 
     370        #define R_X86_64_GOTPC32  26     // 32 
     371        #define R_X86_64_GNU_VTINHERIT 250    // GNU C++ hack 
     372        #define R_X86_64_GNU_VTENTRY   251    // GNU C++ hack 
    370373} Elf64_Rel; 
    371374 
    372375typedef struct { 
    373376    Elf64_Addr   r_offset; 
    374377    Elf64_Xword  r_info; 
    375378    Elf64_Sxword r_addend; 
    376379} Elf64_Rela; 
    377380 
    378381 
  • branches/dmd-1.x/src/backend/out.c

    r493 r572  
    416416                    reftodatseg(seg,offset,dt->DTabytes,DATA,flags); 
    417417                else 
    418418                    reftofarseg(seg,offset,dt->DTabytes,dt->DTseg,flags); 
    419419#endif 
    420420                offset += size(dt->Dty); 
    421421                break; 
    422422            case DT_ibytes: 
    423423                obj_bytes(seg,offset,dt->DTn,dt->DTdata); 
    424424                offset += dt->DTn; 
    425425                break; 
    426426            case DT_nbytes: 
    427427                obj_bytes(seg,offset,dt->DTnbytes,dt->DTpbytes); 
    428428                offset += dt->DTnbytes; 
    429429                break; 
    430430            case DT_azeros: 
    431431                //printf("obj_lidata(seg = %d, offset = %d, azeros = %d)\n", seg, offset, dt->DTazeros); 
    432432                obj_lidata(seg,offset,dt->DTazeros); 
    433433                offset += dt->DTazeros; 
    434434                break; 
    435435            case DT_xoff: 
    436             {   symbol *sb; 
    437  
    438                 sb = dt->DTsym;          // get external symbol pointer 
     436            { 
     437                symbol *sb = dt->DTsym;          // get external symbol pointer 
    439438                a = dt->DToffset; // offset from it 
    440439                if (tyreg(dt->Dty)) 
    441440                    flags = CFoff; 
    442441                else 
    443442                    flags = CFoff | CFseg; 
     443                if (I64) 
     444                    flags |= CFoffset64; 
    444445                offset += reftoident(seg,offset,sb,a,flags); 
    445446                break; 
    446447            } 
    447448            case DT_coff: 
    448449                reftocodseg(seg,offset,dt->DToffset); 
    449450                offset += intsize; 
    450451                break; 
    451452            case DT_1byte: 
    452453                obj_byte(seg,offset++,dt->DTonebyte); 
    453454                break; 
    454455            default: 
    455456#ifdef DEBUG 
    456457                dbg_printf("dt = %p, dt = %d\n",dt,dt->dt); 
    457458#endif 
    458459                assert(0); 
    459460        } 
    460461    } 
    461462#if ELFOBJ || MACHOBJ 
    462463    Offset(seg) = offset; 
    463464#else 
  • branches/dmd-1.x/src/backend/ptrntab.c

    r428 r572  
    826826PTRNTAB2  aptb2IDIV[] = /* IDIV */ { 
    827827        { 0xf6, _7,                     _al,            _rm8 }, 
    828828        { 0xf7, _7|_16_bit|_moddx,              _ax,            _rm16 }, 
    829829        { 0xf7, _7|_32_bit|_moddx,              _eax,           _rm32 }, 
    830830        { 0xf6, _7 | _modax,                    _rm8,           0 }, 
    831831        { 0xf7, _7|_16_bit|_modaxdx,    _rm16,          0 }, 
    832832        { 0xf7, _7|_32_bit|_modaxdx,    _rm32,          0 }, 
    833833        { ASM_END, 0, 0, 0 } 
    834834}; 
    835835PTRNTAB2  aptb2IN[] = /* IN */ { 
    836836        { 0xe4, _ib,        _al,                _imm8 }, 
    837837        { 0xe5, _ib|_16_bit,_ax,                _imm8 }, 
    838838        { 0xe5, _ib|_32_bit,_eax,       _imm8 }, 
    839839        { 0xec, 0,          _al,                _dx }, 
    840840        { 0xed, _16_bit,    _ax,                _dx }, 
    841841        { 0xed, _32_bit,    _eax,       _dx }, 
    842842        { ASM_END, 0, 0, 0 } 
    843843}; 
    844844PTRNTAB2  aptb2INS[] = /* INS */ { 
    845845        { 0x6c, _modsi, _rm8, _dx }, 
    846         { 0x6d, _modsi|_16_bit, _rm16 | _16_bit, _dx }, 
    847         { 0x6d, _32_bit|_modsi, _rm32 | _32_bit, _dx }, 
     846        { 0x6d, _modsi|_16_bit, _rm16, _dx }, 
     847        { 0x6d, _32_bit|_modsi, _rm32, _dx }, 
    848848        { ASM_END, 0, 0, 0 } 
    849849}; 
    850850 
    851851PTRNTAB2  aptb2LAR[] = /* LAR */ { 
    852852        { 0x0f02,       _r|_16_bit,                     _r16,   _rm16 }, 
    853853        { 0x0f02,       _r|_32_bit,                     _r32,   _rm32 }, 
    854854        { ASM_END, 0, 0, 0 } 
    855855}; 
    856856PTRNTAB2  aptb2LDS[] = /* LDS */ { 
    857857        { 0xc5, _r|_16_bit,                     _r16,   _m32 }, 
    858858        { 0xc5, _r|_32_bit,                     _r32,   _m48 }, 
    859859        { ASM_END, 0, 0, 0 } 
    860860}; 
    861861 
    862862PTRNTAB2  aptb2LEA[] = /* LEA */ { 
    863863        { 0x8d, _r|_16_bit,             _r16,   _m8 | _m16 | _m32 | _m48 }, 
    864864        { 0x8d, _r|_32_bit,             _r32,   _m8 | _m16 | _m32 | _m48 }, 
    865865        { 0x8d, _r|_16_bit,             _r16,   _rel16 }, 
    866866        { 0x8d, _r|_32_bit,             _r32,   _rel32 }, 
    867867        { ASM_END, 0, 0, 0 } 
  • branches/dmd-1.x/src/iasm.c

    r487 r572  
    11 
    22/* 
    33 * Copyright (c) 1992-1999 by Symantec 
    4  * Copyright (c) 1999-2009 by Digital Mars 
     4 * Copyright (c) 1999-2010 by Digital Mars 
    55 * All Rights Reserved 
    66 * http://www.digitalmars.com 
    77 * Written by Mike Cote, John Micco and Walter Bright 
    88 * D version by Walter Bright 
    99 * 
    1010 * This source file is made available for personal use 
    1111 * only. The license is in /dmd/src/dmd/backendlicense.txt 
    1212 * For any other uses, please contact Digital Mars. 
    1313 */ 
    1414 
    1515// Inline assembler for the D programming language compiler 
    1616 
    1717#include        <ctype.h> 
    1818#include        <stdlib.h> 
    1919#include        <stdio.h> 
    2020#include        <string.h> 
    2121#include        <time.h> 
    2222#include        <assert.h> 
    2323#include        <setjmp.h> 
    2424#if __DMC__ 
    2525#undef setjmp 
    2626#include        <limits.h> 
    2727#endif 
    2828 
    2929 
    3030// D compiler 
    3131#include        "mars.h" 
    3232#include        "lexer.h" 
    3333#include        "mtype.h" 
    3434#include        "statement.h" 
    3535#include        "id.h" 
    3636#include        "declaration.h" 
    3737#include        "scope.h" 
    3838#include        "init.h" 
    3939#include        "enum.h" 
     40#include        "module.h" 
    4041 
    4142// C/C++ compiler 
    4243#define SCOPE_H 1               // avoid conflicts with D's Scope 
    4344#include        "cc.h" 
    4445#include        "token.h" 
    4546#include        "parser.h" 
    4647#include        "global.h" 
    4748#include        "el.h" 
    4849#include        "type.h" 
    4950#include        "oper.h" 
    5051#include        "code.h" 
    5152#include        "iasm.h" 
    5253#include        "cpp.h" 
    5354 
    5455#undef _DH 
    5556 
    5657// I32 isn't set correctly yet because this is the front end, and I32 
    5758// is a backend flag 
     59#undef I16 
    5860#undef I32 
     61#undef I64 
     62#define I16 0 
    5963#define I32 (global.params.isX86_64 == 0) 
     64#define I64 (global.params.isX86_64 == 1) 
    6065 
    6166//#define EXTRA_DEBUG 1 
    6267 
    6368#undef ADDFWAIT 
    6469#define ADDFWAIT()      0 
    6570 
    6671// Error numbers 
    6772enum ASMERRMSGS 
    6873{ 
    6974    EM_bad_float_op, 
    7075    EM_bad_addr_mode, 
    7176    EM_align, 
    7277    EM_opcode_exp, 
    7378    EM_prefix, 
    7479    EM_eol, 
    7580    EM_bad_operand, 
    7681    EM_bad_integral_operand, 
    7782    EM_ident_exp, 
    7883    EM_not_struct, 
    7984    EM_nops_expected, 
     
    289294"TR6",  6,      _special | _trn, 
    290295"TR7",  7,      _special | _trn, 
    291296"MM0",  0,      _mm, 
    292297"MM1",  1,      _mm, 
    293298"MM2",  2,      _mm, 
    294299"MM3",  3,      _mm, 
    295300"MM4",  4,      _mm, 
    296301"MM5",  5,      _mm, 
    297302"MM6",  6,      _mm, 
    298303"MM7",  7,      _mm, 
    299304"XMM0", 0,      _xmm, 
    300305"XMM1", 1,      _xmm, 
    301306"XMM2", 2,      _xmm, 
    302307"XMM3", 3,      _xmm, 
    303308"XMM4", 4,      _xmm, 
    304309"XMM5", 5,      _xmm, 
    305310"XMM6", 6,      _xmm, 
    306311"XMM7", 7,      _xmm, 
    307312}; 
    308313 
     314// 64 bit only registers 
     315#define _RAX    0 
     316#define _RBX    3 
     317#define _RCX    1 
     318#define _RDX    2 
     319#define _RSI    6 
     320#define _RDI    7 
     321#define _RBP    5 
     322#define _RSP    4 
     323#define _R8     8 
     324#define _R9     9 
     325#define _R10    10 
     326#define _R11    11 
     327#define _R12    12 
     328#define _R13    13 
     329#define _R14    14 
     330#define _R15    15 
     331 
     332#define _R8D    8 
     333#define _R9D    9 
     334#define _R10D   10 
     335#define _R11D   11 
     336#define _R12D   12 
     337#define _R13D   13 
     338#define _R14D   14 
     339#define _R15D   15 
     340 
     341#define _R8W    8 
     342#define _R9W    9 
     343#define _R10W   10 
     344#define _R11W   11 
     345#define _R12W   12 
     346#define _R13W   13 
     347#define _R14W   13 
     348#define _R15W   15 
     349 
     350#define _SIL    6 
     351#define _DIL    7 
     352#define _BPL    5 
     353#define _SPL    4 
     354#define _R8B    8 
     355#define _R9B    9 
     356#define _R10B   10 
     357#define _R11B   11 
     358#define _R12B   12 
     359#define _R13B   13 
     360#define _R14B   14 
     361#define _R15B   15 
     362 
     363static REG regtab64[] = 
     364{ 
     365"RAX",  _RAX,   _r64 | _rax, 
     366"RBX",  _RBX,   _r64, 
     367"RCX",  _RCX,   _r64, 
     368"RDX",  _RDX,   _r64, 
     369"RSI",  _RSI,   _r64, 
     370"RDI",  _RDI,   _r64, 
     371"RBP",  _RBP,   _r64, 
     372"RSP",  _RSP,   _r64, 
     373"R8",   _R8,    _r64, 
     374"R9",   _R9,    _r64, 
     375"R10",  _R10,   _r64, 
     376"R11",  _R11,   _r64, 
     377"R12",  _R12,   _r64, 
     378"R13",  _R13,   _r64, 
     379"R14",  _R14,   _r64, 
     380"R15",  _R15,   _r64, 
     381 
     382"R8D",  _R8D,   _r32, 
     383"R9D",  _R9D,   _r32, 
     384"R10D", _R10D,  _r32, 
     385"R11D", _R11D,  _r32, 
     386"R12D", _R12D,  _r32, 
     387"R13D", _R13D,  _r32, 
     388"R14D", _R14D,  _r32, 
     389"R15D", _R15D,  _r32, 
     390 
     391"R8W",  _R8W,   _r16, 
     392"R9W",  _R9W,   _r16, 
     393"R10W", _R10W,  _r16, 
     394"R11W", _R11W,  _r16, 
     395"R12W", _R12W,  _r16, 
     396"R13W", _R13W,  _r16, 
     397"R14W", _R14W,  _r16, 
     398"R15W", _R15W,  _r16, 
     399 
     400"SIL",  _SIL,   _r8, 
     401"DIL",  _DIL,   _r8, 
     402"BPL",  _BPL,   _r8, 
     403"SPL",  _SPL,   _r8, 
     404"R8B",  _R8B,   _r8, 
     405"R9B",  _R9B,   _r8, 
     406"R10B", _R10B,  _r8, 
     407"R11B", _R11B,  _r8, 
     408"R12B", _R12B,  _r8, 
     409"R13B", _R13B,  _r8, 
     410"R14B", _R14B,  _r8, 
     411"R15B", _R15B,  _r8, 
     412 
     413"XMM8",   8,    _xmm, 
     414"XMM9",   9,    _xmm, 
     415"XMM10", 10,    _xmm, 
     416"XMM11", 11,    _xmm, 
     417"XMM12", 12,    _xmm, 
     418"XMM13", 13,    _xmm, 
     419"XMM14", 14,    _xmm, 
     420"XMM15", 15,    _xmm, 
     421}; 
     422 
    309423typedef enum { 
    310424    ASM_JUMPTYPE_UNSPECIFIED, 
    311425    ASM_JUMPTYPE_SHORT, 
    312426    ASM_JUMPTYPE_NEAR, 
    313427    ASM_JUMPTYPE_FAR 
    314428} ASM_JUMPTYPE;             // ajt 
    315429 
    316430typedef struct opnd 
    317431{ 
    318432        REG *base;              // if plain register 
    319433        REG *pregDisp1;         // if [register1] 
    320434        REG *pregDisp2; 
    321435        REG *segreg;            // if segment override 
    322436        char indirect;          // if had a '*' or '->' 
    323437        char bOffset;           // if 'offset' keyword 
    324438        char bSeg;              // if 'segment' keyword 
    325439        char bPtr;              // if 'ptr' keyword 
    326440        unsigned uchMultiplier; // register multiplier; valid values are 0,1,2,4,8 
    327441        opflag_t usFlags; 
    328442        Dsymbol *s; 
     
    351465int asm_getnum(); 
    352466 
    353467STATIC void asmerr(char *, ...); 
    354468STATIC void asmerr(int, ...); 
    355469#pragma SC noreturn(asmerr) 
    356470 
    357471STATIC OPND *asm_equal_exp(); 
    358472STATIC OPND *asm_inc_or_exp(); 
    359473STATIC OPND *asm_log_and_exp(); 
    360474STATIC OPND *asm_log_or_exp(); 
    361475STATIC char asm_length_type_size(OPND *popnd); 
    362476STATIC void asm_token(); 
    363477STATIC void asm_token_trans(Token *tok); 
    364478STATIC unsigned char asm_match_flags(opflag_t usOp , opflag_t usTable ); 
    365479STATIC unsigned char asm_match_float_flags(opflag_t usOp, opflag_t usTable); 
    366480STATIC void asm_make_modrm_byte( 
    367481#ifdef DEBUG 
    368482        unsigned char *puchOpcode, unsigned *pusIdx, 
    369483#endif 
    370484        code *pc, 
    371         unsigned short usFlags, 
     485        unsigned usFlags, 
    372486        OPND *popnd, OPND *popnd2); 
    373487STATIC regm_t asm_modify_regs(PTRNTAB ptb, OPND *popnd1, OPND *popnd2); 
    374488STATIC void asm_output_flags(opflag_t usFlags); 
    375489STATIC void asm_output_popnd(OPND *popnd); 
    376490STATIC unsigned asm_type_size(Type * ptype); 
    377491STATIC opflag_t asm_float_type_size(Type * ptype, opflag_t *pusFloat); 
    378492STATIC OPND *asm_mul_exp(); 
    379493STATIC OPND *asm_br_exp(); 
    380494STATIC OPND *asm_primary_exp(); 
    381495STATIC OPND *asm_prim_post(OPND *); 
    382496STATIC OPND *asm_rel_exp(); 
    383497STATIC OPND *asm_shift_exp(); 
    384498STATIC OPND *asm_una_exp(); 
    385499STATIC OPND *asm_xor_exp(); 
    386500STATIC void *link_alloc(size_t, void *); 
    387501STATIC void asm_chktok(enum TOK toknum, unsigned errnum); 
    388502STATIC code *asm_db_parse(OP *pop); 
    389503STATIC code *asm_da_parse(OP *pop); 
    390504 
    391 unsigned short compute_hashkey(char *); 
     505unsigned compute_hashkey(char *); 
    392506 
    393507 
    394508/******************************* 
    395509 */ 
    396510 
    397511STATIC OPND *opnd_calloc() 
    398512{   OPND *o; 
    399513 
    400514    o = new OPND(); 
    401515    memset(o, 0, sizeof(*o)); 
    402516    return o; 
    403517} 
    404518 
    405519/******************************* 
    406520 */ 
    407521 
    408522STATIC void opnd_free(OPND *o) 
    409523{ 
    410524    if (o) 
    411525    { 
     
    461575            { 
    462576                popnd2->usFlags = usFlags2 = asm_determine_operand_flags(popnd2); 
    463577                if (!popnd3) 
    464578                    usNumops = 2; 
    465579                else 
    466580                { 
    467581                    popnd3->usFlags = usFlags3 = asm_determine_operand_flags(popnd3); 
    468582                    usNumops = 3; 
    469583                } 
    470584            } 
    471585        } 
    472586 
    473587        // Now check to insure that the number of operands is correct 
    474588        usActual = (pop->usNumops & ITSIZE); 
    475589        if (usActual != usNumops && asmstate.ucItype != ITopt && 
    476590            asmstate.ucItype != ITfloat) 
    477591        { 
    478592PARAM_ERROR: 
    479593                asmerr(EM_nops_expected, usActual, asm_opstr(pop), usNumops); 
    480594        } 
    481         *pusNumops = usNumops; 
     595        *pusNumops = asmstate.ucItype == ITfloat ? usActual : usNumops; 
     596        if (usActual < usNumops) 
     597            *pusNumops = usActual; 
     598        else 
     599            *pusNumops = usNumops; 
    482600// 
    483601//      The number of arguments matches, now check to find the opcode 
    484602//      in the associated opcode table 
    485603// 
    486604RETRY: 
    487605        //printf("usActual = %d\n", usActual); 
    488606        switch (usActual) 
    489607        { 
    490608            case 0: 
    491609                ptbRet = pop->ptb ; 
    492610                goto RETURN_IT; 
    493611 
    494612            case 1: 
    495613                //printf("usFlags1 = "); asm_output_flags(usFlags1); printf("\n"); 
    496614                for (pptb1 = pop->ptb.pptb1; pptb1->usOpcode != ASM_END; 
    497615                        pptb1++) 
    498616                { 
    499617                        //printf("table    = "); asm_output_flags(pptb1->usOp1); printf("\n"); 
    500618                        bMatch1 = asm_match_flags(usFlags1, pptb1->usOp1); 
     619                        //printf("bMatch1 = x%x\n", bMatch1); 
    501620                        if (bMatch1) 
    502621                        {   if (pptb1->usOpcode == 0x68 && 
    503                                 I32 && 
     622                                !I16 && 
    504623                                pptb1->usOp1 == _imm16 
    505624                              ) 
    506625                                // Don't match PUSH imm16 in 32 bit code 
    507626                                continue; 
    508627                            break; 
    509628                        } 
    510629                        if ((asmstate.ucItype == ITimmed) && 
    511630                            asm_match_flags(usFlags1, 
    512631                                CONSTRUCT_FLAGS(_8 | _16 | _32, _imm, _normal, 
    513632                                                 0)) && 
    514633                                popnd1->disp == pptb1->usFlags) 
    515634                            break; 
    516635                        if ((asmstate.ucItype == ITopt || 
    517636                             asmstate.ucItype == ITfloat) && 
    518637                            !usNumops && 
    519638                            !pptb1->usOp1) 
    520639                        { 
    521640                            if (usNumops > 1) 
    522641                                goto PARAM_ERROR; 
    523642                            break; 
     
    785904    } 
    786905    if (popnd->pregDisp1 && !popnd->base) 
    787906    { 
    788907        us = asm_float_type_size(popnd->ptype, &usFloat); 
    789908        //printf("us = x%x, usFloat = x%x\n", us, usFloat); 
    790909        if (popnd->pregDisp1->ty & _r32) 
    791910            return(CONSTRUCT_FLAGS(us, _m, _addr32, usFloat)); 
    792911        else 
    793912        if (popnd->pregDisp1->ty & _r16) 
    794913            return(CONSTRUCT_FLAGS(us, _m, _addr16, usFloat)); 
    795914    } 
    796915    else if (popnd->s != 0) 
    797916    { 
    798917        us = asm_float_type_size(popnd->ptype, &usFloat); 
    799918        return CONSTRUCT_FLAGS(us, _m, _normal, usFloat); 
    800919    } 
    801920 
    802921    if (popnd->segreg) 
    803922    { 
    804923        us = asm_float_type_size(popnd->ptype, &usFloat); 
    805         if (I32) 
     924        if (I16) 
     925            return(CONSTRUCT_FLAGS(us, _m, _addr16, usFloat)); 
     926        else 
    806927            return(CONSTRUCT_FLAGS(us, _m, _addr32, usFloat)); 
    807         else 
    808             return(CONSTRUCT_FLAGS(us, _m, _addr16, usFloat)); 
    809928    } 
    810929 
    811930#if 0 
    812931    if (popnd->real) 
    813932    { 
    814933        switch (popnd->ptype->ty) 
    815934        { 
    816935            case Tfloat32: 
    817936                popnd->s = fconst(popnd->real); 
    818937                return(CONSTRUCT_FLAGS(_32, _m, _normal, 0)); 
    819938 
    820939            case Tfloat64: 
    821940                popnd->s = dconst(popnd->real); 
    822                 return(CONSTRUCT_FLAGS(0, _m, _normal, _64)); 
     941                return(CONSTRUCT_FLAGS(0, _m, _normal, _f64)); 
    823942 
    824943            case Tfloat80: 
    825944                popnd->s = ldconst(popnd->real); 
    826                 return(CONSTRUCT_FLAGS(0, _m, _normal, _80)); 
     945                return(CONSTRUCT_FLAGS(0, _m, _normal, _f80)); 
    827946        } 
    828947    } 
    829948#endif 
    830949 
    831950    asmerr(EM_bad_float_op);    // unknown operand for floating point instruction 
    832951    return 0; 
    833952} 
    834953 
    835954/******************************* 
    836955 */ 
    837956 
    838957STATIC opflag_t asm_determine_operand_flags(OPND *popnd) 
    839958{ 
    840959        Dsymbol *ps; 
    841960        int ty; 
    842961        opflag_t us; 
    843962        opflag_t sz; 
    844963        ASM_OPERAND_TYPE opty; 
    845964        ASM_MODIFIERS amod; 
    846965 
     
    850969 
    851970        if (asmstate.ucItype == ITfloat) 
    852971            return asm_determine_float_flags(popnd); 
    853972 
    854973        // If just a register 
    855974        if (popnd->base && !popnd->s && !popnd->disp && !popnd->real) 
    856975                return popnd->base->ty; 
    857976#if DEBUG 
    858977        if (debuga) 
    859978            printf("popnd->base = %s\n, popnd->pregDisp1 = %p\n", popnd->base ? popnd->base->regstr : "NONE", popnd->pregDisp1); 
    860979#endif 
    861980        ps = popnd->s; 
    862981        Declaration *ds = ps ? ps->isDeclaration() : NULL; 
    863982        if (ds && ds->storage_class & STClazy) 
    864983            sz = _anysize; 
    865984        else 
    866985            sz = asm_type_size((ds && ds->storage_class & (STCout | STCref)) ? popnd->ptype->pointerTo() : popnd->ptype); 
    867986        if (popnd->pregDisp1 && !popnd->base) 
    868987        { 
    869988            if (ps && ps->isLabel() && sz == _anysize) 
    870                 sz = I32 ? _32 : _16
     989                sz = I16 ? _16 : _32
    871990            return (popnd->pregDisp1->ty & _r32) 
    872991                ? CONSTRUCT_FLAGS(sz, _m, _addr32, 0) 
    873992                : CONSTRUCT_FLAGS(sz, _m, _addr16, 0); 
    874993        } 
    875994        else if (ps) 
    876995        { 
    877996                if (popnd->bOffset || popnd->bSeg || ps == asmstate.psLocalsize) 
    878                     return I32 
    879                         ? CONSTRUCT_FLAGS(_32, _imm, _normal, 0) 
    880                         : CONSTRUCT_FLAGS(_16, _imm, _normal, 0); 
     997                    return I16 
     998                        ? CONSTRUCT_FLAGS(_16, _imm, _normal, 0) 
     999                        : CONSTRUCT_FLAGS(_32, _imm, _normal, 0); 
    8811000 
    8821001                if (ps->isLabel()) 
    8831002                { 
    8841003                    switch (popnd->ajt) 
    8851004                    { 
    8861005                        case ASM_JUMPTYPE_UNSPECIFIED: 
    8871006                            if (ps == asmstate.psDollar) 
    8881007                            { 
    8891008                                if (popnd->disp >= CHAR_MIN && 
    8901009                                    popnd->disp <= CHAR_MAX) 
    8911010                                    us = CONSTRUCT_FLAGS(_8, _rel, _flbl,0); 
    8921011                                else 
    8931012                                if (popnd->disp >= SHRT_MIN && 
    8941013                                    popnd->disp <= SHRT_MAX) 
    8951014                                    us = CONSTRUCT_FLAGS(_16, _rel, _flbl,0); 
    8961015                                else 
    8971016                                    us = CONSTRUCT_FLAGS(_32, _rel, _flbl,0); 
    8981017                            } 
    8991018                            else if (asmstate.ucItype != ITjump) 
    9001019                            {   if (sz == _8) 
    9011020                                {   us = CONSTRUCT_FLAGS(_8,_rel,_flbl,0); 
    9021021                                    break; 
    9031022                                } 
    9041023                                goto case_near; 
    9051024                            } 
    9061025                            else 
    907                                 us = I32 
    908                                     ? CONSTRUCT_FLAGS(_8|_32, _rel, _flbl,0) 
    909                                     : CONSTRUCT_FLAGS(_8|_16, _rel, _flbl,0); 
     1026                                us = I16 
     1027                                    ? CONSTRUCT_FLAGS(_8|_16, _rel, _flbl,0) 
     1028                                    : CONSTRUCT_FLAGS(_8|_32, _rel, _flbl,0); 
    9101029                            break; 
    9111030 
    9121031                        case ASM_JUMPTYPE_NEAR: 
    9131032                        case_near: 
    914                             us = I32 
    915                                 ? CONSTRUCT_FLAGS(_32, _rel, _flbl, 0) 
    916                                 : CONSTRUCT_FLAGS(_16, _rel, _flbl, 0); 
     1033                            us = I16 
     1034                                ? CONSTRUCT_FLAGS(_16, _rel, _flbl, 0) 
     1035                                : CONSTRUCT_FLAGS(_32, _rel, _flbl, 0); 
    9171036                            break; 
    9181037                        case ASM_JUMPTYPE_SHORT: 
    9191038                            us = CONSTRUCT_FLAGS(_8, _rel, _flbl, 0); 
    9201039                            break; 
    9211040                        case ASM_JUMPTYPE_FAR: 
    922                             us = I32 
    923                                 ? CONSTRUCT_FLAGS(_48, _rel, _flbl, 0) 
    924                                 : CONSTRUCT_FLAGS(_32, _rel, _flbl, 0); 
     1041                            us = I16 
     1042                                ? CONSTRUCT_FLAGS(_32, _rel, _flbl, 0) 
     1043                                : CONSTRUCT_FLAGS(_48, _rel, _flbl, 0); 
    9251044                            break; 
    9261045                        default: 
    9271046                            assert(0); 
    9281047                    } 
    9291048                    return us; 
    9301049                } 
    9311050                if (!popnd->ptype) 
    9321051                    return CONSTRUCT_FLAGS(sz, _m, _normal, 0); 
    9331052                ty = popnd->ptype->ty; 
    9341053                if (ty == Tpointer && popnd->ptype->nextOf()->ty == Tfunction && 
    9351054                    !ps->isVarDeclaration()) 
    9361055                { 
    9371056#if 1 
    9381057                    return CONSTRUCT_FLAGS(_32, _m, _fn16, 0); 
    9391058#else 
    9401059                    ty = popnd->ptype->Tnext->Tty; 
    9411060                    if (tyfarfunc(tybasic(ty))) { 
    9421061                        return I32 
    9431062                            ? CONSTRUCT_FLAGS(_48, _mnoi, _fn32, 0) 
    9441063                            : CONSTRUCT_FLAGS(_32, _mnoi, _fn32, 0); 
     
    9571076#else 
    9581077                    if (tyfarfunc(tybasic(ty))) 
    9591078                        return I32 
    9601079                            ? CONSTRUCT_FLAGS(_48, _p, _fn32, 0) 
    9611080                            : CONSTRUCT_FLAGS(_32, _p, _fn32, 0); 
    9621081                    else 
    9631082                        return I32 
    9641083                            ? CONSTRUCT_FLAGS(_32, _rel, _fn16, 0) 
    9651084                            : CONSTRUCT_FLAGS(_16, _rel, _fn16, 0); 
    9661085#endif 
    9671086                } 
    9681087                else if (asmstate.ucItype == ITjump) 
    9691088                {   amod = _normal; 
    9701089                    goto L1; 
    9711090                } 
    9721091                else 
    9731092                    return CONSTRUCT_FLAGS(sz, _m, _normal, 0); 
    9741093        } 
    9751094        if (popnd->segreg /*|| popnd->bPtr*/) 
    9761095        { 
    977             amod = I32 ? _addr32 : _addr16
     1096            amod = I16 ? _addr16 : _addr32
    9781097            if (asmstate.ucItype == ITjump) 
    9791098            { 
    9801099            L1: 
    9811100                opty = _m; 
    982                 if (I32) 
     1101                if (I16) 
     1102                {   if (sz == _32) 
     1103                        opty = _mnoi; 
     1104                } 
     1105                else 
    9831106                {   if (sz == _48) 
    984                         opty = _mnoi; 
    985                 } 
    986                 else 
    987                 { 
    988                     if (sz == _32) 
    9891107                        opty = _mnoi; 
    9901108                } 
    9911109                us = CONSTRUCT_FLAGS(sz,opty,amod,0); 
    9921110            } 
    9931111            else 
    9941112                us = CONSTRUCT_FLAGS(sz, 
    9951113//                                   _rel, amod, 0); 
    9961114                                     _m, amod, 0); 
    9971115        } 
    9981116 
    9991117        else if (popnd->ptype) 
    10001118            us = CONSTRUCT_FLAGS(sz, _imm, _normal, 0); 
    10011119 
    10021120        else if (popnd->disp >= CHAR_MIN && popnd->disp <= UCHAR_MAX) 
    10031121            us = CONSTRUCT_FLAGS(_8 | _16 | _32, _imm, _normal, 0); 
    10041122        else if (popnd->disp >= SHRT_MIN && popnd->disp <= USHRT_MAX) 
    10051123            us = CONSTRUCT_FLAGS(_16 | _32, _imm, _normal, 0); 
    10061124        else 
    10071125            us = CONSTRUCT_FLAGS(_32, _imm, _normal, 0); 
    10081126        return us; 
    10091127} 
    10101128 
    10111129/****************************** 
    10121130 * Convert assembly instruction into a code, and append 
    10131131 * it to the code generated for this block. 
    10141132 */ 
    10151133 
    10161134STATIC code *asm_emit(Loc loc, 
    10171135        unsigned usNumops, PTRNTAB ptb, 
    10181136        OP *pop, 
    10191137        OPND *popnd1, OPND *popnd2, OPND *popnd3) 
    10201138{ 
    10211139#ifdef DEBUG 
    10221140        unsigned char auchOpcode[16]; 
    10231141        unsigned usIdx = 0; 
    10241142        #define emit(op)        (auchOpcode[usIdx++] = op) 
    10251143#else 
    10261144        #define emit(op)        ((void)(op)) 
    10271145#endif 
    10281146        Identifier *id; 
    1029 //      unsigned short us; 
     1147//      unsigned us; 
    10301148        unsigned char *puc; 
    10311149        unsigned usDefaultseg; 
    10321150        code *pc = NULL; 
    10331151        OPND *popndTmp; 
    10341152        ASM_OPERAND_TYPE    aoptyTmp; 
    1035         unsigned short uSizemaskTmp; 
     1153        unsigned uSizemaskTmp; 
    10361154        REG     *pregSegment; 
    10371155        code    *pcPrefix = NULL; 
    10381156        unsigned            uSizemask1 =0, uSizemask2 =0, uSizemask3 =0; 
    10391157        //ASM_OPERAND_TYPE    aopty1 = _reg , aopty2 = 0, aopty3 = 0; 
    10401158        ASM_MODIFIERS       amod1 = _normal, amod2 = _normal, amod3 = _normal; 
    10411159        unsigned            uRegmask1 = 0, uRegmask2 =0, uRegmask3 =0; 
    10421160        unsigned            uSizemaskTable1 =0, uSizemaskTable2 =0, 
    10431161                            uSizemaskTable3 =0; 
    10441162        ASM_OPERAND_TYPE    aoptyTable1 = _reg, aoptyTable2 = _reg, aoptyTable3 = _reg; 
    10451163        ASM_MODIFIERS       amodTable1 = _normal, 
    10461164                            amodTable2 = _normal, 
    10471165                            amodTable3 = _normal; 
    10481166        unsigned            uRegmaskTable1 = 0, uRegmaskTable2 =0, 
    10491167                            uRegmaskTable3 =0; 
    10501168 
    10511169        pc = code_calloc(); 
    10521170        pc->Iflags |= CFpsw;            // assume we want to keep the flags 
    10531171        if (popnd1) 
    10541172        { 
    10551173            uSizemask1 = ASM_GET_uSizemask(popnd1->usFlags); 
     
    10801198            uSizemaskTable2 = ASM_GET_uSizemask(ptb.pptb2->usOp2); 
    10811199            aoptyTable2 = ASM_GET_aopty(ptb.pptb2->usOp2); 
    10821200            amodTable2 = ASM_GET_amod(ptb.pptb2->usOp2); 
    10831201            uRegmaskTable2 = ASM_GET_uRegmask(ptb.pptb2->usOp2); 
    10841202        } 
    10851203        if (popnd3) 
    10861204        { 
    10871205            uSizemask3 = ASM_GET_uSizemask(popnd3->usFlags); 
    10881206            //aopty3 = ASM_GET_aopty(popnd3->usFlags); 
    10891207            amod3 = ASM_GET_amod(popnd3->usFlags); 
    10901208            uRegmask3 = ASM_GET_uRegmask(popnd3->usFlags); 
    10911209 
    10921210            uSizemaskTable3 = ASM_GET_uSizemask(ptb.pptb3->usOp3); 
    10931211            aoptyTable3 = ASM_GET_aopty(ptb.pptb3->usOp3); 
    10941212            amodTable3 = ASM_GET_amod(ptb.pptb3->usOp3); 
    10951213            uRegmaskTable3 = ASM_GET_uRegmask(ptb.pptb3->usOp3); 
    10961214        } 
    10971215 
    10981216        asmstate.statement->regs |= asm_modify_regs(ptb, popnd1, popnd2); 
    10991217 
    1100         if (!I32 && ptb.pptb0->usFlags & _I386) 
     1218        if (I16 && ptb.pptb0->usFlags & _I386) 
    11011219        { 
    11021220            switch (usNumops) 
    11031221            { 
    11041222                case 0: 
    11051223                    break; 
    11061224                case 1: 
    11071225                    if (popnd1 && popnd1->s) 
    11081226                    { 
    11091227L386_WARNING: 
    11101228                        id = popnd1->s->ident; 
    11111229L386_WARNING2: 
    11121230                        if (config.target_cpu < TARGET_80386) 
    11131231                        {   // Reference to %s caused a 386 instruction to be generated 
    11141232                            //warerr(WM_386_op, id->toChars()); 
    11151233                        } 
    11161234                    } 
    11171235                    break; 
    11181236                case 2: 
    11191237                case 3:     // The third operand is always an _imm 
    11201238                    if (popnd1 && popnd1->s) 
    11211239                        goto L386_WARNING; 
    11221240                    if (popnd2 && popnd2->s) 
    11231241                    { 
    11241242                        id = popnd2->s->ident; 
    11251243                        goto L386_WARNING2; 
    11261244                    } 
    11271245                    break; 
    11281246            } 
    11291247        } 
    11301248 
    11311249        switch (usNumops) 
    11321250        { 
    11331251            case 0: 
    11341252                if ((I32 && (ptb.pptb0->usFlags & _16_bit)) || 
    1135                         (!I32 && (ptb.pptb0->usFlags & _32_bit))) 
     1253                        (I16 && (ptb.pptb0->usFlags & _32_bit))) 
    11361254                { 
    11371255                        emit(0x66); 
    11381256                        pc->Iflags |= CFopsize; 
    11391257                } 
    11401258                break; 
    11411259 
    11421260            // 3 and 2 are the same because the third operand is always 
    11431261            // an immediate and does not affect operation size 
    11441262            case 3: 
    11451263            case 2: 
    11461264                if ((I32 && 
    11471265                      (amod2 == _addr16 || 
    11481266                       (uSizemaskTable2 & _16 && aoptyTable2 == _rel) || 
    11491267                       (uSizemaskTable2 & _32 && aoptyTable2 == _mnoi) || 
    11501268                       (ptb.pptb2->usFlags & _16_bit_addr) 
    11511269                     ) 
    11521270                    ) || 
    1153                      (!I32 && 
     1271                     (I16 && 
    11541272                       (amod2 == _addr32 || 
    11551273                        (uSizemaskTable2 & _32 && aoptyTable2 == _rel) || 
    11561274                        (uSizemaskTable2 & _48 && aoptyTable2 == _mnoi) || 
    11571275                        (ptb.pptb2->usFlags & _32_bit_addr))) 
    11581276                  ) 
    11591277                { 
    11601278                        emit(0x67); 
    11611279                        pc->Iflags |= CFaddrsize; 
    11621280                        if (I32) 
    11631281                            amod2 = _addr16; 
    11641282                        else 
    11651283                            amod2 = _addr32; 
    11661284                        popnd2->usFlags &= ~CONSTRUCT_FLAGS(0,0,7,0); 
    11671285                        popnd2->usFlags |= CONSTRUCT_FLAGS(0,0,amod2,0); 
    11681286                } 
    11691287 
    11701288 
    11711289            /* Fall through, operand 1 controls the opsize, but the 
    11721290                address size can be in either operand 1 or operand 2, 
    11731291                hence the extra checking the flags tested for SHOULD 
    11741292                be mutex on operand 1 and operand 2 because there is 
    11751293                only one MOD R/M byte 
    11761294             */ 
    11771295 
    11781296            case 1: 
    11791297                if ((I32 && 
    11801298                      (amod1 == _addr16 || 
    11811299                       (uSizemaskTable1 & _16 && aoptyTable1 == _rel) || 
    11821300                        (uSizemaskTable1 & _32 && aoptyTable1 == _mnoi) || 
    11831301                        (ptb.pptb1->usFlags & _16_bit_addr))) || 
    1184                      (!I32 && 
     1302                     (I16 && 
    11851303                      (amod1 == _addr32 || 
    11861304                        (uSizemaskTable1 & _32 && aoptyTable1 == _rel) || 
    11871305                        (uSizemaskTable1 & _48 && aoptyTable1 == _mnoi) || 
    11881306                         (ptb.pptb1->usFlags & _32_bit_addr)))) 
    11891307                { 
    11901308                        emit(0x67);     // address size prefix 
    11911309                        pc->Iflags |= CFaddrsize; 
    11921310                        if (I32) 
    11931311                            amod1 = _addr16; 
    11941312                        else 
    11951313                            amod1 = _addr32; 
    11961314                        popnd1->usFlags &= ~CONSTRUCT_FLAGS(0,0,7,0); 
    11971315                        popnd1->usFlags |= CONSTRUCT_FLAGS(0,0,amod1,0); 
    11981316                } 
    11991317 
    12001318                // If the size of the operand is unknown, assume that it is 
    12011319                // the default size 
    12021320                if ((I32 && (ptb.pptb0->usFlags & _16_bit)) || 
    1203                     (!I32 && (ptb.pptb0->usFlags & _32_bit))) 
     1321                    (I16 && (ptb.pptb0->usFlags & _32_bit))) 
    12041322                { 
    12051323                    //if (asmstate.ucItype != ITjump) 
    12061324                    {   emit(0x66); 
    12071325                        pc->Iflags |= CFopsize; 
    12081326                    } 
    12091327                } 
    12101328                if (((pregSegment = (popndTmp = popnd1)->segreg) != NULL) || 
    12111329                        ((popndTmp = popnd2) != NULL && 
    12121330                        (pregSegment = popndTmp->segreg) != NULL) 
    12131331                  ) 
    12141332                { 
    12151333                    if ((popndTmp->pregDisp1 && 
    12161334                            popndTmp->pregDisp1->val == _BP) || 
    12171335                            popndTmp->pregDisp2 && 
    12181336                            popndTmp->pregDisp2->val == _BP) 
    12191337                            usDefaultseg = _SS; 
    12201338                    else 
    12211339                            usDefaultseg = _DS; 
    12221340                    if (pregSegment->val != usDefaultseg) 
    12231341                        switch (pregSegment->val) { 
     
    17331851    va_end(ap); 
    17341852 
    17351853    printf("\n"); 
    17361854    fflush(stdout); 
    17371855 
    17381856    longjmp(asmstate.env,1); 
    17391857} 
    17401858 
    17411859/******************************* 
    17421860 */ 
    17431861 
    17441862STATIC opflag_t asm_float_type_size(Type *ptype, opflag_t *pusFloat) 
    17451863{ 
    17461864    *pusFloat = 0; 
    17471865 
    17481866    //printf("asm_float_type_size('%s')\n", ptype->toChars()); 
    17491867    if (ptype && ptype->isscalar()) 
    17501868    { 
    17511869        int sz = (int)ptype->size(); 
    17521870        if (sz == REALSIZE) 
    1753         {   *pusFloat = _80; 
     1871        {   *pusFloat = _f80; 
    17541872            return 0; 
    17551873        } 
    17561874        switch (sz) 
    17571875        { 
    17581876            case 2: 
    17591877                return _16; 
    17601878            case 4: 
    17611879                return _32; 
    17621880            case 8: 
    1763                 *pusFloat = _64; 
     1881                *pusFloat = _f64; 
     1882                return 0; 
     1883            case 10: 
     1884                *pusFloat = _f80; 
    17641885                return 0; 
    17651886            default: 
    17661887                break; 
    17671888        } 
    17681889    } 
    17691890    *pusFloat = _fanysize; 
    17701891    return _anysize; 
    17711892} 
    17721893 
    17731894/******************************* 
    17741895 */ 
    17751896 
    17761897STATIC int asm_isint(OPND *o) 
    17771898{ 
    17781899    if (!o || o->base || o->s) 
    17791900        return 0; 
    17801901    //return o->disp != 0; 
    17811902    return 1; 
    17821903} 
    17831904 
     
    19932114    { 
    19942115        if (v->isParameter()) 
    19952116            asmstate.statement->refparam = TRUE; 
    19962117 
    19972118        v->checkNestedReference(asmstate.sc, asmstate.loc); 
    19982119#if 0 
    19992120        if (!v->isDataseg() && v->parent != asmstate.sc->parent && v->parent) 
    20002121        { 
    20012122            asmerr(EM_uplevel, v->toChars()); 
    20022123        } 
    20032124#endif 
    20042125        if (v->storage_class & STCfield) 
    20052126        { 
    20062127            o1->disp += v->offset; 
    20072128            goto L2; 
    20082129        } 
    20092130        if ((v->isConst() 
    20102131#if DMDV2 
    20112132                || v->isImmutable() || v->storage_class & STCmanifest 
    20122133#endif 
    2013             ) && !v->type->isfloating()
     2134            ) && !v->type->isfloating() && v->init
    20142135        {   ExpInitializer *ei = v->init->isExpInitializer(); 
    20152136 
    20162137            if (ei) 
    20172138            { 
    20182139                o1->disp = ei->exp->toInteger(); 
    20192140                return; 
    20202141            } 
    20212142        } 
    20222143    } 
    20232144    em = s->isEnumMember(); 
    20242145    if (em) 
    20252146    { 
    20262147        o1->disp = em->value->toInteger(); 
    20272148        return; 
    20282149    } 
    20292150    o1->s = s;  // a C identifier 
    20302151L2: 
    20312152    Declaration *d = s->isDeclaration(); 
    20322153    if (!d) 
    20332154    { 
    20342155        asmerr("%s %s is not a declaration", s->kind(), s->toChars()); 
    20352156    } 
    20362157    else if (d->getType()) 
    20372158        asmerr(EM_type_as_operand, d->getType()->toChars()); 
    20382159    else if (d->isTupleDeclaration()) 
    20392160        ; 
    20402161    else 
    20412162        o1->ptype = d->type->toBasetype(); 
    20422163} 
    20432164 
    20442165/**************************** 
    20452166 * Fill in the modregrm and sib bytes of code. 
    20462167 */ 
    20472168 
    20482169STATIC void asm_make_modrm_byte( 
    20492170#ifdef DEBUG 
    20502171        unsigned char *puchOpcode, unsigned *pusIdx, 
    20512172#endif 
    20522173        code *pc, 
    2053         unsigned short usFlags, 
     2174        unsigned usFlags, 
    20542175        OPND *popnd, OPND *popnd2) 
    20552176{ 
    20562177    #undef modregrm 
    20572178 
    20582179    typedef union { 
    20592180        unsigned char   uchOpcode; 
    20602181        struct { 
    20612182            unsigned rm  : 3; 
    20622183            unsigned reg : 3; 
    20632184            unsigned mod : 2; 
    20642185        } modregrm; 
    20652186    } MODRM_BYTE;                       // mrmb 
    20662187 
    20672188    typedef union { 
    20682189        unsigned char   uchOpcode; 
    20692190        struct { 
    20702191            unsigned base  : 3; 
    20712192            unsigned index : 3; 
    20722193            unsigned ss    : 2; 
    20732194        } sib; 
    20742195    } SIB_BYTE; 
    20752196 
    20762197 
    20772198    MODRM_BYTE  mrmb = { 0 }; 
    20782199    SIB_BYTE    sib = { 0 }; 
    20792200    char                bSib = FALSE; 
    20802201    char                bDisp = FALSE; 
    20812202    char                b32bit = FALSE; 
    20822203    unsigned char       *puc; 
    20832204    char                bModset = FALSE; 
    20842205    Dsymbol             *s; 
    20852206 
    20862207    unsigned        uSizemask =0; 
    20872208    ASM_OPERAND_TYPE    aopty; 
    20882209    ASM_MODIFIERS           amod; 
    2089     unsigned short          uRegmask; 
     2210    unsigned          uRegmask; 
    20902211    unsigned char           bOffsetsym = FALSE; 
    20912212 
    20922213#if 0 
    20932214    printf("asm_make_modrm_byte(usFlags = x%x)\n", usFlags); 
    20942215    printf("op1: "); 
    20952216    asm_output_flags(popnd->usFlags); 
    20962217    if (popnd2) 
    20972218    {   printf(" op2: "); 
    20982219        asm_output_flags(popnd2->usFlags); 
    20992220    } 
    21002221    printf("\n"); 
    21012222#endif 
    21022223 
    21032224    uSizemask = ASM_GET_uSizemask(popnd->usFlags); 
    21042225    aopty = ASM_GET_aopty(popnd->usFlags); 
    21052226    amod = ASM_GET_amod(popnd->usFlags); 
    21062227    uRegmask = ASM_GET_uRegmask(popnd->usFlags); 
    21072228    s = popnd->s; 
    21082229    if (s) 
    21092230    { 
     
    21902311    } 
    21912312    mrmb.modregrm.reg = usFlags & NUM_MASK; 
    21922313 
    21932314    if (s && (aopty == _m || aopty == _mnoi) && !s->isLabel()) 
    21942315    { 
    21952316        if (s == asmstate.psLocalsize) 
    21962317        { 
    21972318    DATA_REF: 
    21982319            mrmb.modregrm.rm = BPRM; 
    21992320            if (amod == _addr16 || amod == _addr32) 
    22002321                mrmb.modregrm.mod = 0x2; 
    22012322            else 
    22022323                mrmb.modregrm.mod = 0x0; 
    22032324        } 
    22042325        else 
    22052326        { 
    22062327            Declaration *d = s->isDeclaration(); 
    22072328            assert(d); 
    22082329            if (d->isDataseg() || d->isCodeseg()) 
    22092330            { 
    2210                 if (( I32 && amod == _addr16) || 
    2211                     (!I32 && amod == _addr32)) 
     2331                if ((I32 && amod == _addr16) || 
     2332                    (I16 && amod == _addr32)) 
    22122333                    asmerr(EM_bad_addr_mode);   // illegal addressing mode 
    22132334                goto DATA_REF; 
    22142335            } 
    22152336            mrmb.modregrm.rm = BPRM; 
    22162337            mrmb.modregrm.mod = 0x2; 
    22172338        } 
    22182339    } 
    22192340 
    22202341    if (aopty == _reg || amod == _rspecial) { 
    22212342            mrmb.modregrm.mod = 0x3; 
    22222343            mrmb.modregrm.rm |= popnd->base->val; 
    22232344    } 
    2224     else if (amod == _addr16 || (amod == _flbl && !I32)) 
     2345    else if (amod == _addr16 || (amod == _flbl && I16)) 
    22252346    {   unsigned rm; 
    22262347 
    22272348#ifdef DEBUG 
    22282349        if (debuga) 
    22292350            printf("This is an ADDR16\n"); 
    22302351#endif 
    22312352        if (!popnd->pregDisp1) 
    22322353        {   rm = 0x6; 
    22332354            if (!s) 
    22342355                bDisp = TRUE; 
    22352356        } 
    22362357        else 
    22372358        {   unsigned r1r2; 
    22382359            #define X(r1,r2)    (((r1) * 16) + (r2)) 
    22392360            #define Y(r1)               X(r1,9) 
    22402361 
    22412362 
    22422363            if (popnd->pregDisp2) 
    22432364                r1r2 = X(popnd->pregDisp1->val,popnd->pregDisp2->val); 
    22442365            else 
     
    26152736} 
    26162737 
    26172738/******************************* 
    26182739 * Match flags in operand against flags in opcode table. 
    26192740 * Returns: 
    26202741 *      !=0 if match 
    26212742 */ 
    26222743 
    26232744STATIC unsigned char asm_match_flags(opflag_t usOp, opflag_t usTable) 
    26242745{ 
    26252746    ASM_OPERAND_TYPE    aoptyTable; 
    26262747    ASM_OPERAND_TYPE    aoptyOp; 
    26272748    ASM_MODIFIERS       amodTable; 
    26282749    ASM_MODIFIERS       amodOp; 
    26292750    unsigned            uRegmaskTable; 
    26302751    unsigned            uRegmaskOp; 
    26312752    unsigned char       bRegmatch; 
    26322753    unsigned char       bRetval = FALSE; 
    26332754    unsigned            uSizemaskOp; 
    26342755    unsigned            uSizemaskTable; 
    2635     unsigned char       bSizematch; 
     2756    unsigned            bSizematch; 
    26362757 
    26372758    //printf("asm_match_flags(usOp = x%x, usTable = x%x)\n", usOp, usTable); 
    26382759    if (asmstate.ucItype == ITfloat) 
    26392760    { 
    26402761        bRetval = asm_match_float_flags(usOp, usTable); 
    26412762        goto EXIT; 
    26422763    } 
    26432764 
    26442765    uSizemaskOp = ASM_GET_uSizemask(usOp); 
    26452766    uSizemaskTable = ASM_GET_uSizemask(usTable); 
    26462767 
    26472768    // Check #1, if the sizes do not match, NO match 
    26482769    bSizematch =  (uSizemaskOp & uSizemaskTable); 
    26492770 
    26502771    amodOp = ASM_GET_amod(usOp); 
    26512772 
    26522773    aoptyTable = ASM_GET_aopty(usTable); 
    26532774    aoptyOp = ASM_GET_aopty(usOp); 
    26542775 
    26552776    // _mmm64 matches with a 64 bit mem or an MMX register 
     
    27412862    printf(": %s\n", bRetval ? "MATCH" : "NOMATCH"); 
    27422863#endif 
    27432864    return bRetval; 
    27442865 
    27452866Lmatch: 
    27462867    //printf("match\n"); 
    27472868    return 1; 
    27482869} 
    27492870 
    27502871/******************************* 
    27512872 */ 
    27522873 
    27532874STATIC unsigned char asm_match_float_flags(opflag_t usOp, opflag_t usTable) 
    27542875{ 
    27552876    ASM_OPERAND_TYPE    aoptyTable; 
    27562877    ASM_OPERAND_TYPE    aoptyOp; 
    27572878    ASM_MODIFIERS       amodTable; 
    27582879    ASM_MODIFIERS       amodOp; 
    27592880    unsigned            uRegmaskTable; 
    27602881    unsigned            uRegmaskOp; 
    2761     unsigned char       bRegmatch; 
     2882    unsigned            bRegmatch; 
    27622883 
    27632884 
    27642885// 
    27652886// Check #1, if the sizes do not match, NO match 
    27662887// 
    27672888    uRegmaskOp = ASM_GET_uRegmask(usOp); 
    27682889    uRegmaskTable = ASM_GET_uRegmask(usTable); 
    27692890    bRegmatch = (uRegmaskTable & uRegmaskOp); 
    27702891 
    27712892    if (!(ASM_GET_uSizemask(usTable) & ASM_GET_uSizemask(usOp) || 
    27722893          bRegmatch)) 
    27732894        return(FALSE); 
    27742895 
    27752896    aoptyTable = ASM_GET_aopty(usTable); 
    27762897    aoptyOp = ASM_GET_aopty(usOp); 
    27772898// 
    27782899// The operand types must match, otherwise return FALSE. 
    27792900// There is one exception for the _rm which is a table entry which matches 
    27802901// _reg or _m 
    27812902// 
     
    28242945{ 
    28252946        ASM_OPERAND_TYPE    aopty = ASM_GET_aopty(usFlags); 
    28262947        ASM_MODIFIERS       amod = ASM_GET_amod(usFlags); 
    28272948        unsigned            uRegmask = ASM_GET_uRegmask(usFlags); 
    28282949        unsigned            uSizemask = ASM_GET_uSizemask(usFlags); 
    28292950 
    28302951        if (uSizemask == _anysize) 
    28312952            printf("_anysize "); 
    28322953        else if (uSizemask == 0) 
    28332954            printf("0        "); 
    28342955        else 
    28352956        { 
    28362957            if (uSizemask & _8) 
    28372958                printf("_8  "); 
    28382959            if (uSizemask & _16) 
    28392960                printf("_16 "); 
    28402961            if (uSizemask & _32) 
    28412962                printf("_32 "); 
    28422963            if (uSizemask & _48) 
    28432964                printf("_48 "); 
     2965            if (uSizemask & _64) 
     2966                printf("_64 "); 
    28442967        } 
    28452968 
    28462969        printf("_"); 
    28472970        switch (aopty) { 
    28482971            case _reg: 
    28492972                printf("reg   "); 
    28502973                break; 
    28512974            case _m: 
    28522975                printf("m     "); 
    28532976                break; 
    28542977            case _imm: 
    28552978                printf("imm   "); 
    28562979                break; 
    28572980            case _rel: 
    28582981                printf("rel   "); 
    28592982                break; 
    28602983            case _mnoi: 
    28612984                printf("mnoi  "); 
    28622985                break; 
    28632986            case _p: 
     
    28652988                break; 
    28662989            case _rm: 
    28672990                printf("rm    "); 
    28682991                break; 
    28692992            case _float: 
    28702993                printf("float "); 
    28712994                break; 
    28722995            default: 
    28732996                printf(" UNKNOWN "); 
    28742997        } 
    28752998 
    28762999        printf("_"); 
    28773000        switch (amod) { 
    28783001            case _normal: 
    28793002                printf("normal   "); 
    28803003                if (uRegmask & 1) printf("_al "); 
    28813004                if (uRegmask & 2) printf("_ax "); 
    28823005                if (uRegmask & 4) printf("_eax "); 
    28833006                if (uRegmask & 8) printf("_dx "); 
    28843007                if (uRegmask & 0x10) printf("_cl "); 
     3008                if (uRegmask & 0x40) printf("_rax "); 
     3009                if (uRegmask & 0x20) printf("_rplus_r "); 
    28853010                return; 
    28863011            case _rseg: 
    28873012                printf("rseg     "); 
    28883013                break; 
    28893014            case _rspecial: 
    28903015                printf("rspecial "); 
    28913016                break; 
    28923017            case _addr16: 
    28933018                printf("addr16   "); 
    28943019                break; 
    28953020            case _addr32: 
    28963021                printf("addr32   "); 
    28973022                break; 
    28983023            case _fn16: 
    28993024                printf("fn16     "); 
    29003025                break; 
    29013026            case _fn32: 
    29023027                printf("fn32     "); 
    29033028                break; 
    29043029            case _flbl: 
     
    29603085} 
    29613086 
    29623087#endif 
    29633088 
    29643089/******************************* 
    29653090 */ 
    29663091 
    29673092STATIC REG *asm_reg_lookup(char *s) 
    29683093{ 
    29693094    int i; 
    29703095 
    29713096    //dbg_printf("asm_reg_lookup('%s')\n",s); 
    29723097 
    29733098    for (i = 0; i < sizeof(regtab) / sizeof(regtab[0]); i++) 
    29743099    { 
    29753100        if (strcmp(s,regtab[i].regstr) == 0) 
    29763101        { 
    29773102            return &regtab[i]; 
    29783103        } 
    29793104    } 
     3105    if (I64) 
     3106    { 
     3107        for (i = 0; i < sizeof(regtab64) / sizeof(regtab64[0]); i++) 
     3108        { 
     3109            if (strcmp(s,regtab64[i].regstr) == 0) 
     3110            { 
     3111                return &regtab64[i]; 
     3112            } 
     3113        } 
     3114    } 
    29803115    return NULL; 
    29813116} 
    29823117 
    29833118 
    29843119/******************************* 
    29853120 */ 
    29863121 
    29873122STATIC void asm_token() 
    29883123{ 
    29893124    if (asmtok) 
    29903125        asmtok = asmtok->next; 
    29913126    asm_token_trans(asmtok); 
    29923127} 
    29933128 
    29943129/******************************* 
    29953130 */ 
    29963131 
    29973132STATIC void asm_token_trans(Token *tok) 
    29983133{ 
    29993134    tok_value = TOKeof; 
     
    30163151    } 
    30173152} 
    30183153 
    30193154/******************************* 
    30203155 */ 
    30213156 
    30223157STATIC unsigned asm_type_size(Type * ptype) 
    30233158{   unsigned u; 
    30243159 
    30253160    //if (ptype) printf("asm_type_size('%s') = %d\n", ptype->toChars(), (int)ptype->size()); 
    30263161    u = _anysize; 
    30273162    if (ptype && ptype->ty != Tfunction /*&& ptype->isscalar()*/) 
    30283163    { 
    30293164        switch ((int)ptype->size()) 
    30303165        { 
    30313166            case 0:     asmerr(EM_bad_op, "0 size");    break; 
    30323167            case 1:     u = _8;         break; 
    30333168            case 2:     u = _16;        break; 
    30343169            case 4:     u = _32;        break; 
    30353170            case 6:     u = _48;        break; 
     3171            case 8:     if (I64) u = _64;        break; 
    30363172        } 
    30373173    } 
    30383174    return u; 
    30393175} 
    30403176 
    30413177/******************************* 
    30423178 *      start of inline assemblers expression parser 
    30433179 *      NOTE: functions in call order instead of alphabetical 
    30443180 */ 
    30453181 
    30463182/******************************************* 
    30473183 * Parse DA expression 
    30483184 * 
    30493185 * Very limited define address to place a code 
    30503186 * address in the assembly 
    30513187 * Problems: 
    30523188 *      o       Should use dw offset and dd offset instead, 
    30533189 *              for near/far support. 
    30543190 *      o       Should be able to add an offset to the label address. 
    30553191 *      o       Blocks addressed by DA should get their Bpred set correctly 
     
    42154351 * Return mask of registers used by block bp. 
    42164352 */ 
    42174353 
    42184354regm_t iasm_regs(block *bp) 
    42194355{ 
    42204356#ifdef DEBUG 
    42214357    if (debuga) 
    42224358        printf("Block iasm regs = 0x%X\n", bp->usIasmregs); 
    42234359#endif 
    42244360 
    42254361    refparam |= bp->bIasmrefparam; 
    42264362    return bp->usIasmregs; 
    42274363} 
    42284364 
    42294365 
    42304366/************************ AsmStatement ***************************************/ 
    42314367 
    42324368Statement *AsmStatement::semantic(Scope *sc) 
    42334369{ 
    42344370    //printf("AsmStatement::semantic()\n"); 
     4371 
     4372#if DMDV2 
     4373    if (sc->func && sc->func->isSafe()) 
     4374        error("inline assembler not allowed in @safe function %s", sc->func->toChars()); 
     4375#endif 
     4376 
    42354377    OP *o; 
    42364378    OPND *o1 = NULL,*o2 = NULL, *o3 = NULL; 
    42374379    PTRNTAB ptb; 
    42384380    unsigned usNumops; 
    42394381    unsigned char uchPrefix = 0; 
    42404382    unsigned char bAsmseen; 
    42414383    char *pszLabel = NULL; 
    42424384    code *c; 
    42434385    FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 
    42444386 
    42454387    assert(fd); 
    42464388    fd->inlineAsm = 1; 
    42474389 
    42484390    if (!tokens) 
    42494391        return NULL; 
    42504392 
    42514393    memset(&asmstate, 0, sizeof(asmstate)); 
    42524394 
    42534395    asmstate.statement = this; 
    42544396    asmstate.sc = sc; 
  • trunk/src/backend/code.h

    r569 r572  
    369369#define CFjmp16           2     // need 16 bit jump offset (long branch) 
    370370#define CFtarg            4     // this code is the target of a jump 
    371371#define CFseg             8     // get segment of immediate value 
    372372#define CFoff          0x10     // get offset of immediate value 
    373373#define CFss           0x20     // generate an SS: segment override (not with 
    374374                                // CFes at the same time, though!) 
    375375#define CFpsw          0x40     // we need the flags result after this instruction 
    376376#define CFopsize       0x80     // prefix with operand size 
    377377#define CFaddrsize    0x100     // prefix with address size 
    378378#define CFds          0x200     // need DS override (not with es, ss, or cs ) 
    379379#define CFcs          0x400     // need CS override 
    380380#define CFfs          0x800     // need FS override 
    381381#define CFgs    (CFcs | CFfs)   // need GS override 
    382382#define CFwait       0x1000     // If I32 it indicates when to output a WAIT 
    383383#define CFselfrel    0x2000     // if self-relative 
    384384#define CFunambig    0x4000     // indicates cannot be accessed by other addressing 
    385385                                // modes 
    386386#define CFtarg2      0x8000     // like CFtarg, but we can't optimize this away 
    387387#define CFvolatile  0x10000     // volatile reference, do not schedule 
    388388#define CFclassinit 0x20000     // class init code 
     389#define CFoffset64  0x40000     // offset is 64 bits 
    389390 
    390391#define CFPREFIX (CFSEG | CFopsize | CFaddrsize) 
    391392#define CFSEG   (CFes | CFss | CFds | CFcs | CFfs | CFgs) 
    392393 
    393394    unsigned char Irex;         // REX prefix 
    394395 
    395396    unsigned char Iop; 
    396397    unsigned char Irm;          // reg/mode 
    397398 
    398399    unsigned char Iop2;         // second opcode byte 
    399400    unsigned char Isib;         // SIB byte 
    400401 
    401402    unsigned char Iop3;         // third opcode byte 
    402403 
    403404    unsigned char IFL1,IFL2;    // FLavors of 1st, 2nd operands 
    404405    union evc IEV1;             // 1st operand, if any 
    405406      #define IEVpointer1 IEV1._EP.Vpointer 
    406407      #define IEVseg1     IEV1._EP.Vseg 
    407408      #define IEVsym1     IEV1.sp.Vsym 
    408409      #define IEVdsym1    IEV1.dsp.Vsym 
  • trunk/src/backend/el.h

    r442 r572  
    11// Copyright (C) 1985-1995 by Symantec 
    2 // Copyright (C) 2000-2009 by Digital Mars 
     2// Copyright (C) 2000-2010 by Digital Mars 
    33// All Rights Reserved 
    44// http://www.digitalmars.com 
    55// Written by Walter Bright 
    66/* 
    77 * This source file is made available for personal use 
    88 * only. The license is in /dmd/src/dmd/backendlicense.txt 
    99 * or /dm/src/dmd/backendlicense.txt 
    1010 * For any other uses, please contact Digital Mars. 
    1111 */ 
    1212 
    1313/* Routines to handle elems.                            */ 
    1414 
    1515#if __SC__ 
    1616#pragma once 
    1717#endif 
    1818 
    1919#ifndef EL_H 
    2020#define EL_H    1 
    2121 
    2222#if TARGET_MAC 
     
    108108        { 
    109109            // Ety2: Must be in same position as Ety! 
    110110            tym_t Ety2_;                        // data type (TYxxxx) 
    111111            #define Ety2 _EU._EC.Ety2_ 
    112112            unsigned char Ecomsub_;     // number of remaining references to 
    113113                                        // this common subexp (used to determine 
    114114                                        // first, intermediate, and last references 
    115115                                        // to a CSE) 
    116116            #define Ecomsub _EU._EC.Ecomsub_ 
    117117 
    118118#if TARGET_POWERPC 
    119119            unsigned char Gflags; 
    120120            #define     GFLassrval      1               // element is rvalue of an assign 
    121121            #define     GFLsignok       2               // element does not need sign extend 
    122122            #define     GFLstrthis_fixed        4       // strthis child elem has been fixed 
    123123                                                        // on first pass, do not do it again 
    124124#endif 
    125125        }_EC; 
    126126    }_EU; 
    127127 
    128     targ_size_t Enumbytes;      // number of bytes for type if TYstruct | TYarray 
     128    unsigned Enumbytes;         // number of bytes for type if TYstruct | TYarray 
    129129    TARGET_structELEM           // target specific additions 
    130130    Srcpos Esrcpos;             // source file position 
    131131}; 
    132132 
    133133#define typemask(e)     ((!MARS && PARSER) ? (e)->ET->Tty : (e)->Ety ) 
    134134#define typetym(e)      ((e)->ET->Tty) 
    135135#define el_fl(e)        ((enum FL)((e)->EV.sp.Vsym->Sfl)) 
    136136#define Eoffset         EV.sp.Voffset 
    137137#define Esymnum         EV.sp.Vsymnum 
    138138 
    139139#define list_elem(list) ((elem *) list_ptr(list)) 
    140140#define list_setelem(list,ptr) list_ptr(list) = (elem *)(ptr) 
    141141#define cnst(e) ((e)->Eoper == OPconst) /* Determine if elem is a constant */ 
    142142#define E1        EV.eop.Eleft          /* left child                   */ 
    143143#define E2        EV.eop.Eright         /* right child                  */ 
    144144#define Erd       EV.sp.spu.Erd         // reaching definition 
    145145 
    146146#define el_int(a,b)     el_long(a,b) 
    147147  
    148148typedef elem *elem_p;   /* try to reduce the symbol table size  */ 
  • trunk/src/backend/elfobj.c

    r569 r572  
    4141//#define DEBSYM 0x7E 
    4242 
    4343static Outbuffer *fobjbuf; 
    4444 
    4545regm_t BYTEREGS = BYTEREGS_INIT; 
    4646regm_t ALLREGS = ALLREGS_INIT; 
    4747 
    4848static char __file__[] = __FILE__;      // for tassert.h 
    4949#include        "tassert.h" 
    5050 
    5151#define MATCH_SECTION 1 
    5252 
    5353#define DEST_LEN (IDMAX + IDOHD + 1) 
    5454char *obj_mangle2(Symbol *s,char *dest); 
    5555 
    5656#if MARS 
    5757// C++ name mangling is handled by front end 
    5858#define cpp_mangle(s) ((s)->Sident) 
    5959#endif 
    6060 
     61/*************************************************** 
     62 * Correspondence of relocation types 
     63 *      386             32 bit in 64      64 in 64 
     64 *      RI_TYPE_SYM32   R_X86_64_32       R_X86_64_64 
     65 *      RI_TYPE_GOTOFF  R_X86_64_PC32     R_X86_64_ 
     66 *      RI_TYPE_GOTPC   R_X86_64_         R_X86_64_ 
     67 *      RI_TYPE_GOT32   R_X86_64_         R_X86_64_ 
     68 *      RI_TYPE_TLS_GD  R_X86_64_TLSGD    R_X86_64_ 
     69 *      RI_TYPE_TLS_IE  R_X86_64_GOTTPOFF R_X86_64_ 
     70 *      RI_TYPE_TLS_LE  R_X86_64_TPOFF32  R_X86_64_ 
     71 *      RI_TYPE_PLT32   R_X86_64_PLT32    R_X86_64_ 
     72 *      RI_TYPE_PC32    R_X86_64_PC32     R_X86_64_ 
     73 */ 
    6174 
    6275/****************************************** 
    6376 */ 
    6477 
    6578symbol *GOTsym; // global offset table reference 
    6679 
    6780symbol *elfobj_getGOTsym() 
    6881{ 
    6982    if (!GOTsym) 
    7083    { 
    7184        GOTsym = symbol_name("_GLOBAL_OFFSET_TABLE_",SCglobal,tspvoid); 
    7285    } 
    7386    return GOTsym; 
    7487} 
    7588 
    7689static void objfile_write(FILE *fd, void *buffer, unsigned len); 
    7790 
    7891STATIC char * objmodtoseg (const char *modname); 
    7992STATIC void obj_browse_flush(); 
    8093STATIC void objfixupp (struct FIXUP *); 
    8194STATIC void ledata_new (int seg,targ_size_t offset); 
    82 static int obj_align(Symbol *s); 
    8395void obj_tlssections(); 
    8496 
    8597static IDXSYM elf_addsym(IDXSTR sym, targ_size_t val, unsigned sz, 
    8698                        unsigned typ,unsigned bind,IDXSEC sec); 
    8799static long elf_align(FILE *fd, targ_size_t size, long offset); 
    88100 
    89101// The object file is built is several separate pieces 
    90102 
    91103// Non-repeatable section types have single output buffers 
    92104//      Pre-allocated buffers are defined for: 
    93105//              Section Names string table 
    94106//              Section Headers table 
    95107//              Symbol table 
    96108//              String table 
    97109//              Notes section 
    98110//              Comment data 
    99111 
    100112// Section Names  - String table for section names only 
    101113static Outbuffer *section_names; 
    102114#define SEC_NAMES_INIT  800 
     
    12361248{ 
    12371249    //dbg_printf("obj_exestr(char *%s)\n",p); 
    12381250} 
    12391251 
    12401252/************************** 
    12411253 * Embed string in obj. 
    12421254 */ 
    12431255 
    12441256void obj_user(const char *p) 
    12451257{ 
    12461258    //dbg_printf("obj_user(char *%s)\n",p); 
    12471259} 
    12481260 
    12491261/******************************* 
    12501262 * Output a weak extern record. 
    12511263 */ 
    12521264 
    12531265void obj_wkext(Symbol *s1,Symbol *s2) 
    12541266{ 
    12551267    //dbg_printf("obj_wkext(Symbol *%s,Symbol *s2)\n",s1->Sident,s2->Sident); 
    1256 #if 0 
    1257     char buffer[2+2+2]; 
    1258     int i; 
    1259  
    1260     buffer[0] = 0x80; 
    1261     buffer[1] = 0xA8; 
    1262     i = 2; 
    1263     i += insidx(&buffer[2],s1->Sxtrnnum); 
    1264     i += insidx(&buffer[i],s2->Sxtrnnum); 
    1265     objrecord(COMENT,buffer,i); 
    1266 #endif 
    12671268} 
    12681269 
    12691270/******************************* 
    12701271 * Output file name record. 
    12711272 * 
    12721273 * Currently assumes that obj_filename will not be called 
    12731274 *      twice for the same file. 
    12741275 */ 
    12751276 
    12761277void obj_filename(const char *modname) 
    1277 {   unsigned strtab_idx; 
    1278     unsigned symtab_idx; 
    1279  
     1278
    12801279    //dbg_printf("obj_filename(char *%s)\n",modname); 
    1281     strtab_idx = elf_addstr(symtab_strings,modname); 
     1280    unsigned strtab_idx = elf_addstr(symtab_strings,modname); 
    12821281    elf_addsym(strtab_idx,0,0,STT_FILE,STB_LOCAL,SHT_ABS); 
    12831282} 
    12841283 
    12851284/******************************* 
    12861285 * Embed compiler version in .obj file. 
    12871286 */ 
    12881287 
    12891288void obj_compiler() 
    12901289{ 
    12911290    //dbg_printf("obj_compiler\n"); 
    12921291    comment_data = new Outbuffer(); 
    12931292    comment_data->write(compiler,sizeof(compiler)); 
    12941293    //dbg_printf("Comment data size %d\n",comment_data->size()); 
    12951294} 
    12961295 
    1297 #if 0 
    1298 /******************************** 
    1299  * Convert module name to code segment name. 
    1300  * Output: 
    1301  *      mem_malloc'd code seg name 
    1302  */ 
    1303  
    1304 STATIC char * objmodtoseg(const char *modname) 
    1305 {   char *csegname = NULL; 
    1306  
    1307     if (LARGECODE)              // if need to add in module name 
    1308     {   int i; 
    1309         char *m; 
    1310         static const char suffix[] = "_TEXT"; 
    1311  
    1312         // Prepend the module name to the beginning of the _TEXT 
    1313         m = filespecgetroot(filespecname(modname)); 
    1314         strupr(m); 
    1315         i = strlen(m); 
    1316         csegname = mem_malloc(i + sizeof(suffix)); 
    1317         strcpy(csegname,m); 
    1318         strcat(csegname,suffix); 
    1319         mem_free(m); 
    1320     } 
    1321     return csegname; 
    1322 } 
    1323 #endif 
    13241296 
    13251297//#if NEWSTATICDTOR 
    13261298 
    13271299/************************************** 
    13281300 * Symbol is the function that calls the static constructors. 
    13291301 * Put a pointer to it into a special segment that the startup code 
    13301302 * looks at. 
    13311303 * Input: 
    13321304 *      s       static constructor function 
    13331305 *      dtor    !=0 if leave space for static destructor 
    13341306 *      seg     1:      user 
    13351307 *              2:      lib 
    13361308 *              3:      compiler 
    13371309 */ 
    13381310 
    13391311void obj_staticctor(Symbol *s,int dtor,int none) 
    13401312{ 
    13411313// Static constructors and destructors 
    13421314    IDXSEC seg; 
    13431315    Outbuffer *buf; 
    13441316 
    13451317    //dbg_printf("obj_staticctor(%s) offset %x\n",s->Sident,s->Soffset); 
    13461318    //symbol_print(s); 
    13471319    s->Sseg = seg = 
    13481320        elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, 4); 
    13491321    buf = SegData[seg]->SDbuf; 
    13501322    if (I64) 
    13511323        buf->write64(s->Soffset); 
    13521324    else 
    13531325        buf->write32(s->Soffset); 
    1354     elf_addrel(seg,SegData[seg]->SDoffset,RI_TYPE_SYM32,STI_TEXT,0); 
     1326    elf_addrel(seg,SegData[seg]->SDoffset,I64 ? R_X86_64_64 : RI_TYPE_SYM32,STI_TEXT,0); 
    13551327    SegData[seg]->SDoffset = buf->size(); 
    13561328} 
    13571329 
    13581330/************************************** 
    13591331 * Symbol is the function that calls the static destructors. 
    13601332 * Put a pointer to it into a special segment that the exit code 
    13611333 * looks at. 
    13621334 * Input: 
    13631335 *      s       static destructor function 
    13641336 */ 
    13651337 
    13661338void obj_staticdtor(Symbol *s) 
    13671339{ 
    13681340    IDXSEC seg; 
    13691341    Outbuffer *buf; 
    13701342 
    13711343    //dbg_printf("obj_staticdtor(%s) offset %x\n",s->Sident,s->Soffset); 
    13721344    //symbol_print(s); 
    13731345    seg = elf_getsegment(".dtors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, 4); 
    13741346    buf = SegData[seg]->SDbuf; 
    13751347    if (I64) 
    13761348        buf->write64(s->Soffset); 
    13771349    else 
    13781350        buf->write32(s->Soffset); 
    1379     //elf_addrel(seg,0,RI_TYPE_SYM32,STI_TEXT,0); 
    1380     elf_addrel(seg,SegData[seg]->SDoffset,RI_TYPE_SYM32,s->Sxtrnnum,0); 
     1351    elf_addrel(seg,SegData[seg]->SDoffset,I64 ? R_X86_64_64 : RI_TYPE_SYM32,s->Sxtrnnum,0); 
    13811352    SegData[seg]->SDoffset = buf->size(); 
    13821353} 
    13831354 
    13841355//#else 
    13851356 
    13861357/*************************************** 
    13871358 * Stuff pointer to function in its own segment. 
    13881359 * Used for static ctor and dtor lists. 
    13891360 */ 
    13901361 
    13911362void obj_funcptr(Symbol *s) 
    13921363{ 
    13931364    //dbg_printf("obj_funcptr(%s) \n",s->Sident); 
    13941365} 
    13951366 
    13961367//#endif 
    13971368 
    13981369/*************************************** 
    13991370 * Stuff the following data in a separate segment: 
    14001371 *      pointer to function 
    14011372 *      pointer to ehsym 
    14021373 *      length of function 
    14031374 */ 
    14041375 
    14051376void obj_ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym) 
    14061377{ 
    14071378    //dbg_printf("obj_ehtables(%s) \n",sfunc->Sident); 
    14081379 
    1409     symbol *ehtab_entry; 
    1410     dt_t **pdte; 
    1411  
    1412     ehtab_entry = symbol_generate(SCstatic,type_alloc(TYint)); 
     1380    symbol *ehtab_entry = symbol_generate(SCstatic,type_alloc(TYint)); 
    14131381    symbol_keep(ehtab_entry); 
    14141382    elf_getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14151383    ehtab_entry->Sseg = elf_getsegment(".deh_eh", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14161384    elf_getsegment(".deh_end", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14171385    ehtab_entry->Stype->Tmangle = mTYman_c; 
    14181386    ehsym->Stype->Tmangle = mTYman_c; 
    1419     pdte = &ehtab_entry->Sdt; 
     1387    dt_t **pdte = &ehtab_entry->Sdt; 
    14201388    pdte = dtxoff(pdte,sfunc,0,TYnptr); 
    14211389    pdte = dtxoff(pdte,ehsym,0,TYnptr); 
    14221390    pdte = dtnbytes(pdte,4,(char *)&sfunc->Ssize); 
    14231391    outdata(ehtab_entry); 
    14241392} 
    14251393 
    14261394/********************************************* 
    14271395 * Put out symbols that define the beginning/end of the .deh_eh section. 
    14281396 */ 
    14291397 
    14301398void obj_ehsections() 
    1431 {   int sec; 
    1432     IDXSYM symidx; 
    1433     IDXSTR namidx; 
    1434  
    1435     sec = elf_getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
     1399
     1400    int sec = elf_getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14361401    //obj_bytes(sec, 0, 4, NULL); 
    14371402 
    1438     namidx = elf_addstr(symtab_strings,"_deh_beg"); 
     1403    IDXSTR namidx = elf_addstr(symtab_strings,"_deh_beg"); 
    14391404    elf_addsym(namidx, 0, 0, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec)); 
    14401405    //elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec)); 
    14411406 
    14421407    elf_getsegment(".deh_eh", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14431408 
    14441409    sec = elf_getsegment(".deh_end", NULL, SHT_PROGDEF, SHF_ALLOC, 4); 
    14451410    namidx = elf_addstr(symtab_strings,"_deh_end"); 
    14461411    elf_addsym(namidx, 0, 0, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec)); 
    14471412 
    14481413    obj_tlssections(); 
    14491414} 
    14501415 
    14511416/********************************************* 
    14521417 * Put out symbols that define the beginning/end of the thread local storage sections. 
    14531418 */ 
    14541419 
    14551420void obj_tlssections() 
    14561421{ 
    14571422    IDXSTR namidx; 
    14581423 
     
    16761641 * won't be storing D gc roots in their tls. 
    16771642 * Output: 
    16781643 *      seg_tlsseg      set to segment number for TLS segment. 
    16791644 * Returns: 
    16801645 *      segment for TLS segment 
    16811646 */ 
    16821647 
    16831648seg_data *obj_tlsseg() 
    16841649{ 
    16851650    /* Ensure that ".tdata" precedes any other .tdata. section, as the ld 
    16861651     * linker script fails to work right. 
    16871652     */ 
    16881653    elf_getsegment(".tdata", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
    16891654 
    16901655    static const char tlssegname[] = ".tdata."; 
    16911656    //dbg_printf("obj_tlsseg(\n"); 
    16921657 
    16931658    if (seg_tlsseg == UNKNOWN) 
    16941659    { 
    16951660        seg_tlsseg = elf_getsegment(tlssegname, NULL, SHT_PROGDEF, 
    1696             SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
     1661            SHF_ALLOC|SHF_WRITE|SHF_TLS, I64 ? 16 : 4); 
    16971662    } 
    16981663    return SegData[seg_tlsseg]; 
    16991664} 
    17001665 
    17011666 
    17021667/********************************* 
    17031668 * Define segments for Thread Local Storage. 
    17041669 * Output: 
    17051670 *      seg_tlsseg_bss  set to segment number for TLS segment. 
    17061671 * Returns: 
    17071672 *      segment for TLS segment 
    17081673 */ 
    17091674 
    17101675seg_data *obj_tlsseg_bss() 
    17111676{ 
    17121677    static const char tlssegname[] = ".tbss"; 
    17131678    //dbg_printf("obj_tlsseg_bss(\n"); 
    17141679 
    17151680    if (seg_tlsseg_bss == UNKNOWN) 
    17161681    { 
    17171682        seg_tlsseg_bss = elf_getsegment(tlssegname, NULL, SHT_NOBITS, 
    1718             SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
     1683            SHF_ALLOC|SHF_WRITE|SHF_TLS, I64 ? 16 : 4); 
    17191684    } 
    17201685    return SegData[seg_tlsseg_bss]; 
    17211686} 
    17221687 
    17231688 
    17241689/******************************* 
    17251690 * Output an alias definition record. 
    17261691 */ 
    17271692 
    17281693void obj_alias(const char *n1,const char *n2) 
    1729 {   unsigned len; 
    1730     char *buffer; 
    1731  
     1694
    17321695    dbg_printf("obj_alias(%s,%s)\n",n1,n2); 
    17331696    assert(0); 
    17341697#if NOT_DONE 
    1735     buffer = (char *) alloca(strlen(n1) + strlen(n2) + 2 * ONS_OHD); 
    1736     len = obj_namestring(buffer,n1); 
     1698    char *buffer = (char *) alloca(strlen(n1) + strlen(n2) + 2 * ONS_OHD); 
     1699    unsigned len = obj_namestring(buffer,n1); 
    17371700    len += obj_namestring(buffer + len,n2); 
    17381701    objrecord(ALIAS,buffer,len); 
    17391702#endif 
    17401703} 
    17411704 
    1742 char *unsstr (unsigned value) 
    1743 { 
    1744     static char buffer [64]; 
    1745  
    1746     sprintf (buffer, "%d", value); 
     1705char *unsstr(unsigned value) 
     1706{ 
     1707    static char buffer[64]; 
     1708 
     1709    sprintf(buffer, "%d", value); 
    17471710    return buffer; 
    17481711} 
    17491712 
    17501713/******************************* 
    17511714 * Mangle a name. 
    17521715 * Returns: 
    17531716 *      mangled name 
    17541717 */ 
    17551718 
    17561719char *obj_mangle2(Symbol *s,char *dest) 
    17571720{ 
    1758     size_t len; 
    17591721    char *name; 
    17601722 
    17611723    //dbg_printf("obj_mangle('%s'), mangle = x%x\n",s->Sident,type_mangle(s->Stype)); 
    17621724    symbol_debug(s); 
    17631725    assert(dest); 
    17641726#if SCPP 
    17651727    name = CPP ? cpp_mangle(s) : s->Sident; 
    17661728#elif MARS 
    17671729    name = cpp_mangle(s); 
    17681730#else 
    17691731    name = s->Sident; 
    17701732#endif 
    1771     len = strlen(name);                 // # of bytes in name 
     1733    size_t len = strlen(name);                 // # of bytes in name 
    17721734    //dbg_printf("len %d\n",len); 
    17731735    switch (type_mangle(s->Stype)) 
    17741736    { 
    17751737        case mTYman_pas:                // if upper case 
    17761738        case mTYman_for: 
    17771739            if (len >= DEST_LEN) 
    17781740                dest = (char *)mem_malloc(len + 1); 
    17791741            memcpy(dest,name,len + 1);  // copy in name and ending 0 
    17801742            for (int i = 0; 1; i++) 
    17811743            {   char c = dest[i]; 
    17821744                if (!c) 
    17831745                    break; 
    17841746                if (c >= 'a' && c <= 'z') 
    17851747                    dest[i] = c + 'A' - 'a'; 
    17861748            } 
    17871749            break; 
    17881750        case mTYman_std: 
    17891751#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS 
    17901752            if (tyfunc(s->ty()) && !variadic(s->Stype)) 
    17911753#else 
     
    18151777            memcpy(dest,name,len+1);// copy in name and trailing 0 
    18161778            break; 
    18171779 
    18181780        default: 
    18191781#ifdef DEBUG 
    18201782            printf("mangling %x\n",type_mangle(s->Stype)); 
    18211783            symbol_print(s); 
    18221784#endif 
    18231785            printf("%d\n", type_mangle(s->Stype)); 
    18241786            assert(0); 
    18251787    } 
    18261788    //dbg_printf("\t %s\n",dest); 
    18271789    return dest; 
    18281790} 
    18291791 
    18301792/******************************* 
    18311793 * Export a function name. 
    18321794 */ 
    18331795 
    18341796void obj_export(Symbol *s,unsigned argsize) 
    1835 {   char *coment; 
    1836     size_t len; 
    1837  
     1797
    18381798    //dbg_printf("obj_export(%s,%d)\n",s->Sident,argsize); 
    18391799 
    18401800} 
    18411801 
    18421802/******************************* 
    18431803 * Update data information about symbol 
    18441804 *      align for output and assign segment 
    18451805 *      if not already specified. 
    18461806 * 
    18471807 * Input: 
    18481808 *      sdata           data symbol 
    18491809 *      datasize        output size 
    18501810 *      seg             default seg if not known 
    18511811 * Returns: 
    18521812 *      actual seg 
    18531813 */ 
    18541814 
    18551815int elf_data_start(Symbol *sdata, targ_size_t datasize, int seg) 
    18561816{ 
    18571817    targ_size_t alignbytes; 
     
    19851944    return symidx; 
    19861945} 
    19871946 
    19881947int objextdef(const char *name) 
    19891948{ 
    19901949    return objextern(name); 
    19911950} 
    19921951 
    19931952/******************************* 
    19941953 * Output an external for existing symbol. 
    19951954 * Input: 
    19961955 *      s       Symbol to do EXTDEF on 
    19971956 *              (Name is to be mangled) 
    19981957 * Returns: 
    19991958 *      Symbol table index of the definition 
    20001959 *      NOTE: Numbers will not be linear. 
    20011960 */ 
    20021961 
    20031962int objextern(Symbol *s) 
    20041963{ 
    2005     IDXSTR namidx; 
    20061964    int symtype,sectype; 
    2007     targ_size_t size; 
     1965    unsigned size; 
    20081966 
    20091967    //dbg_printf("objextern('%s') %x\n",s->Sident,s->Svalue); 
    20101968    symbol_debug(s); 
    2011     namidx = elf_addmangled(s); 
     1969    IDXSTR namidx = elf_addmangled(s); 
    20121970 
    20131971#if SCPP 
    20141972    if (s->Sscope && !tyfunc(s->ty())) 
    20151973    { 
    20161974        symtype = STT_OBJECT; 
    20171975        sectype = SHT_COMMON; 
    20181976        size = type_size(s->Stype); 
    20191977    } 
    20201978    else 
    20211979#endif 
    20221980    { 
    20231981        symtype = STT_NOTYPE; 
    20241982        sectype = SHT_UNDEF; 
    20251983        size = 0; 
    20261984    } 
    20271985    if (s->ty() & mTYthread) 
    20281986    { 
    20291987        //printf("objextern('%s') %x TLS\n",s->Sident,s->Svalue); 
    20301988        symtype = STT_TLS; 
    20311989    } 
     
    20341992        /*(s->ty() & mTYweak) ? STB_WEAK : */STB_GLOBAL, sectype); 
    20351993    return s->Sxtrnnum; 
    20361994 
    20371995} 
    20381996 
    20391997/******************************* 
    20401998 * Output a common block definition. 
    20411999 * Input: 
    20422000 *      p ->    external identifier 
    20432001 *      size    size in bytes of each elem 
    20442002 *      count   number of elems 
    20452003 * Returns: 
    20462004 *      Symbol table index for symbol 
    20472005 */ 
    20482006 
    20492007int obj_comdef(Symbol *s,targ_size_t size,targ_size_t count) 
    20502008{ 
    20512009    //printf("obj_comdef('%s',%d,%d)\n",s->Sident,size,count); 
    20522010    symbol_debug(s); 
    20532011 
     2012    int align = I64 ? 16 : 4; 
    20542013    if (s->ty() & mTYthread) 
    20552014    { 
    20562015        s->Sseg = elf_getsegment(".tbss.", cpp_mangle(s), 
    2057                 SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4); 
     2016                SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, align); 
    20582017        s->Sfl = FLtlsdata; 
    20592018        SegData[s->Sseg]->SDsym = s; 
    20602019        SegData[s->Sseg]->SDoffset += size * count; 
    20612020        objpubdef(s->Sseg, s, 0); 
    20622021        searchfixlist(s); 
    20632022        return s->Sseg; 
    20642023    } 
    20652024    else 
    20662025    { 
    20672026        s->Sseg = elf_getsegment(".bss.", cpp_mangle(s), 
    2068                 SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4); 
     2027                SHT_NOBITS, SHF_ALLOC|SHF_WRITE, align); 
    20692028        s->Sfl = FLudata; 
    20702029        SegData[s->Sseg]->SDsym = s; 
    20712030        SegData[s->Sseg]->SDoffset += size * count; 
    20722031        objpubdef(s->Sseg, s, 0); 
    20732032        searchfixlist(s); 
    20742033        return s->Sseg; 
    20752034    } 
    20762035#if 0 
    20772036    IDXSTR namidx = elf_addmangled(s); 
    20782037    alignOffset(UDATA,size); 
    20792038    IDXSYM symidx = elf_addsym(namidx, SegData[UDATA]->SDoffset, size*count, 
    20802039                    (s->ty() & mTYthread) ? STT_TLS : STT_OBJECT, 
    20812040                    STB_WEAK, SHI_BSS); 
    20822041    //dbg_printf("\tobj_comdef returning symidx %d\n",symidx); 
    20832042    s->Sseg = UDATA; 
    20842043    s->Sfl = FLudata; 
    20852044    SegData[UDATA]->SDoffset += size * count; 
    20862045    return symidx; 
    20872046#endif 
    20882047} 
     
    23452304 *              reftodatseg(DATA,offset,3 * sizeof(int *),UDATA); 
    23462305 */ 
    23472306 
    23482307void reftodatseg(int seg,targ_size_t offset,targ_size_t val, 
    23492308        unsigned targetdatum,int flags) 
    23502309{ 
    23512310    Outbuffer *buf; 
    23522311    int save; 
    23532312 
    23542313    buf = SegData[seg]->SDbuf; 
    23552314    save = buf->size(); 
    23562315    buf->setsize(offset); 
    23572316    //dbg_printf("reftodatseg(seg=%d, offset=x%lx, val=x%lx,data %x, flags %x )\n", 
    23582317    //  seg,offset,val,targetdatum,flags); 
    23592318    /*if (OPT_IS_SET(OPTfwritable_strings)) 
    23602319    { 
    23612320        elf_addrel(seg,offset,RI_TYPE_SYM32,STI_DATA,0); 
    23622321    } 
    23632322    else*/ 
    23642323    { 
    2365         unsigned type = RI_TYPE_SYM32; 
    2366  
    2367         if (MAP_SEG2TYP(seg) == CODE && config.flags3 & CFG3pic) 
    2368             type = RI_TYPE_GOTOFF; 
    2369         else if (MAP_SEG2SEC(targetdatum)->sh_flags & SHF_TLS) 
    2370             type = config.flags3 & CFG3pic ? RI_TYPE_TLS_GD : RI_TYPE_TLS_LE; 
    2371  
    2372         elf_addrel(seg,offset,type,STI_RODAT,0); 
    2373     } 
    2374     if (I64) 
    2375         buf->write64(val); 
    2376     else 
    2377         buf->write32(val); 
    2378     if (save > offset + NPTRSIZE) 
     2324        int relinfo; 
     2325 
     2326        if (I64) 
     2327        { 
     2328            if (MAP_SEG2TYP(seg) == CODE && config.flags3 & CFG3pic) 
     2329                relinfo = R_X86_64_PC32; 
     2330            else if (MAP_SEG2SEC(targetdatum)->sh_flags & SHF_TLS) 
     2331                relinfo = config.flags3 & CFG3pic ? R_X86_64_TLSGD : R_X86_64_TPOFF32; 
     2332            else 
     2333                relinfo = R_X86_64_32; 
     2334        } 
     2335        else 
     2336        { 
     2337            if (MAP_SEG2TYP(seg) == CODE && config.flags3 & CFG3pic) 
     2338                relinfo = RI_TYPE_GOTOFF; 
     2339            else if (MAP_SEG2SEC(targetdatum)->sh_flags & SHF_TLS) 
     2340                relinfo = config.flags3 & CFG3pic ? RI_TYPE_TLS_GD : RI_TYPE_TLS_LE; 
     2341            else 
     2342                relinfo = RI_TYPE_SYM32; 
     2343        } 
     2344 
     2345        elf_addrel(seg, offset, relinfo, STI_RODAT, 0); 
     2346    } 
     2347    buf->write32(val); 
     2348    if (save > offset + 4) 
    23792349        buf->setsize(save); 
    23802350} 
    23812351 
    23822352/******************************* 
    23832353 * Refer to address that is in the code segment. 
    23842354 * Only offsets are output, regardless of the memory model. 
    23852355 * Used to put values in switch address tables. 
    23862356 * Input: 
    23872357 *      seg =           where the address is going (CODE or DATA) 
    23882358 *      offset =        offset within seg 
    23892359 *      val =           displacement from start of this module 
    23902360 */ 
    23912361 
    23922362void reftocodseg(int seg,targ_size_t offset,targ_size_t val) 
    23932363{ 
    23942364    Outbuffer *buf; 
    23952365    int save; 
    23962366    int segtyp = MAP_SEG2TYP(seg); 
    23972367 
    23982368    //dbg_printf("reftocodseg(seg=%d, offset=x%lx, val=x%lx )\n",seg,offset,val); 
    23992369    assert(seg > 0);            // COMDATs not done yet 
    24002370