Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.23
 
1.24
 
MAIN:ragge:20121213160215
 
code.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 44  *
 55  * Redistribution and use in source and binary forms, with or without
 66  * modification, are permitted provided that the following conditions
 77  * are met:
 88  *
 99  * Redistributions of source code and documentation must retain the above
 1010  * copyright notice, this list of conditions and the following disclaimer.
 1111  * Redistributions in binary form must reproduce the above copyright
 1212  * notice, this list of conditionsand the following disclaimer in the
 1313  * documentation and/or other materials provided with the distribution.
 1414  * All advertising materials mentioning features or use of this software
 1515  * must display the following acknowledgement:
 1616  *      This product includes software developed or owned by Caldera
 1717  *      International, Inc.
 1818  * Neither the name of Caldera International, Inc. nor the names of other
 1919  * contributors may be used to endorse or promote products derived from
 2020  * this software without specific prior written permission.
 2121  *
 2222  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 2323  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 2424  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 2525  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 2626  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 2727  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 2828  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 2929  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 3030  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 3131  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 3232  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 3333  * POSSIBILITY OF SUCH DAMAGE.
 3434  */
 3535 
 3636 # include "pass1.h"
 3737 
 3838 /*
 3939  * Print out assembler segment name.
 4040  */
 4141 void
 4242 setseg(int seg, char *name)
 4343 {
 4444         switch (seg) {
 4545         case PROG: name = ".text"; break;
 4646 
 4747         case DATA:
 4848         case LDATA: name = ".data"; break;
 4949 
 5050         case STRNG:
 5151         case RDATA: name = ".section .rodata"; break;
 5252 
 5353         case UDATA: break;
 5454 
 5555         case DTORS:
 5656                 name = ".section .dtors,\"aw\",@progbits";
 5757                 break;
 5858         case CTORS:
 5959                 name = ".section .ctors,\"aw\",@progbits";
 6060                 break;
 6161 
 6262         case TLSDATA:
 6363         case TLSUDATA:
 6464                 uerror("FIXME: unsupported segment %d", seg);
 6565                 break;
 6666 
 6767         case PICRDATA:
 6868                 name = ".section .data.rel.ro.local,\"aw\",@progbits";
 6969                 break;
 7070 
<>71 -        case PICLDATA:
7271         case PICDATA:
<> 72+                name = ".section .data.rel,\"aw\",@progbits";
  73+                break;
  74+        case PICLDATA:
7375                 name = ".section .data.rel.local,\"aw\",@progbits";
 7476                 break;
 7577 
 7678         case NMSEG:
 7779                 printf("\t.section %s,\"aw\",@progbits\n", name);
 7880                 return;
 7981         }
 8082         printf("\t%s\n", name);
 8183 }
 8284 
 8385 /*
 8486  * Define everything needed to print out some data (or text).
 8587  * This means segment, alignment, visibility, etc.
 8688  */
 8789 void
 8890 defloc(struct symtab *sp)
 8991 {
 9092         char *name;
 9193 
 9294         if ((name = sp->soname) == NULL)
 9395                 name = exname(sp->sname);
 9496 
 9597         if (sp->sclass == EXTDEF) {
 9698                 printf("\t.globl %s\n", name);
<>97 -                printf("\t.type %s,@%s\n", name,
 98 -                    ISFTN(sp->stype)? "function" : "object");
  99+                if (ISFTN(sp->stype)) {
  100+                        printf("\t.type %s,@function\n", name);
  101+                } else {
  102+                        printf("\t.type %s,@object\n", name);
  103+                        printf("\t.size %s,%d\n", name,
  104+                            (int)tsize(sp->stype, sp->sdf, sp->sap)/SZCHAR);
  105+                }
<_99106         }
 100107         if (sp->slevel == 0)
 101108                 printf("%s:\n", name);
 102109         else
 103110                 printf(LABFMT ":\n", sp->soffset);
 104111 }
 105112 
 106113 static int strtemp;
 107114 
 108115 void
 109116 efcode(void)
 110117 {
 111118         TWORD t;
 112119         NODE *p, *q;
 113120 
 114121         /* code for the end of a function */
 115122         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
 116123                 return;
 117124 
 118125         t = PTR+BTYPE(cftnsp->stype);
 119126         /* Create struct assignment */
 120127         q = tempnode(strtemp, t, 0, cftnsp->sap);
 121128         q = buildtree(UMUL, q, NIL);
 122129         p = block(REG, NIL, NIL, t, 0, cftnsp->sap);
 123130         regno(p) = R0;
 124131         p = buildtree(UMUL, p, NIL);
 125132         p = buildtree(ASSIGN, q, p);
 126133         ecomp(p);
 127134 
 128135         /* put hidden arg in r0 on return */
 129136         q = tempnode(strtemp, INT, 0, 0);
 130137         p = block(REG, NIL, NIL, INT, 0, 0);
 131138         regno(p) = R0;
 132139         ecomp(buildtree(ASSIGN, p, q));
 133140 }
 134141 
 135142 void
 136143 bfcode(struct symtab **sp, int n)
 137144 {
 138145         struct symtab *sp2;
 139146         NODE *p, *q;
 140147         int i;
 141148 
 142149         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
 143150                 /* Move return address into temporary */
 144151                 p = tempnode(0, INT, 0, 0);
 145152                 strtemp = regno(p);
 146153                 q = block(REG, 0, 0, INT, 0, 0);
 147154                 regno(q) = R1;
 148155                 ecomp(buildtree(ASSIGN, p, q));
 149156         }
 150157         if (xtemps == 0)
 151158                 return;
 152159 
 153160         /* put arguments in temporaries */
 154161         for (i = 0; i < n; i++) {
 155162                 if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
 156163                     cisreg(sp[i]->stype) == 0)
 157164                         continue;
 158165                 if (cqual(sp[i]->stype, sp[i]->squal) & VOL)
 159166                         continue;
 160167                 sp2 = sp[i];
 161168                 p = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->sap);
 162169                 p = buildtree(ASSIGN, p, nametree(sp2));
 163170                 sp[i]->soffset = regno(p->n_left);
 164171                 sp[i]->sflags |= STNODE;
 165172                 ecomp(p);
 166173         }
 167174 
 168175 }
 169176 
 170177 void
 171178 ejobcode(int flag)
 172179 {
 173180         /* called just before final exit */
 174181         /* flag is 1 if errors, 0 if none */
 175182 }
 176183 
 177184 void
 178185 bjobcode(void)
 179186 {
 180187         astypnames[INT] = astypnames[UNSIGNED] = "\t.long";
 181188         astypnames[SHORT] = astypnames[USHORT] = "\t.word";
 182189 }
 183190 
 184191 #if 0
 185192 aobeg(void)
 186193 {
 187194         /* called before removing automatics from stab */
 188195 }
 189196 
 190197 aocode(struct symtab *p)
 191198 {
 192199         /* called when automatic p removed from stab */
 193200 }
 194201 
 195202 aoend(void)
 196203 {
 197204         /* called after removing all automatics from stab */
 198205 }
 199206 #endif
 200207 
 201208 void
 202209 fldty(struct symtab *p)
 203210 {
 204211         /* fix up type of field p */
 205212 }
 206213 
 207214 /*
 208215  * XXX - fix genswitch.
 209216  */
 210217 int
 211218 mygenswitch(int num, TWORD type, struct swents **p, int n)
 212219 {
 213220         return 0;
 214221 }
 215222 
 216223 #ifdef notyet
 217224 struct sw heapsw[SWITSZ];       /* heap for switches */
 218225 
 219226 genswitch(register struct sw *p, int n)
 220227 {
 221228         /*      p points to an array of structures, each consisting
 222229                 of a constant value and a label.
 223230                 The first is >=0 if there is a default label;
 224231                 its value is the label number
 225232                 The entries p[1] to p[n] are the nontrivial cases
 226233                 */
 227234         register i;
 228235         register CONSZ j, range;
 229236         register dlab, swlab;
 230237 
 231238         range = p[n].sval-p[1].sval;
 232239 
 233240         if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */
 234241 
 235242                 swlab = getlab();
 236243                 dlab = p->slab >= 0 ? p->slab : getlab();
 237244 
 238245                 /* already in r0 */
 239246                 printf("        casel   r0,$%ld,$%ld\n", p[1].sval, range);
 240247                 deflab1(swlab);
 241248                 for( i=1,j=p[1].sval; i<=n; j++) {
 242249                         printf("        .word   " LABFMT "-" LABFMT "\n",
 243250                             (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),
 244251                                 swlab);
 245252                         }
 246253 
 247254                 if( p->slab >= 0 ) branch( dlab );
 248255                 else deflab1(dlab);
 249256                 return;
 250257 
 251258                 }
 252259 
 253260         if( n>8 ) {     /* heap switch */
 254261 
 255262                 heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();
 256263                 makeheap(p, n, 1);      /* build heap */
 257264 
 258265                 walkheap(1, n); /* produce code */
 259266 
 260267                 if( p->slab >= 0 )
 261268                         branch( dlab );
 262269                 else
 263270                         deflab1(dlab);
 264271                 return;
 265272         }
 266273 
 267274         /* debugging code */
 268275 
 269276         /* out for the moment
 270277         if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
 271278         */
 272279 
 273280         /* simple switch code */
 274281 
 275282         for( i=1; i<=n; ++i ){
 276283                 /* already in r0 */
 277284 
 278285                 printf( "       cmpl    r0,$" );
 279286                 printf( CONFMT, p[i].sval );
 280287                 printf( "\n     jeql    " LBLFMT "\n", p[i].slab );
 281288                 }
 282289 
 283290         if( p->slab>=0 ) branch( p->slab );
 284291 }
 285292 
 286293 makeheap(register struct sw *p, int m, int n)
 287294 {
 288295         register int q;
 289296 
 290297         q = select(m);
 291298         heapsw[n] = p[q];
 292299         if( q>1 ) makeheap(p, q-1, 2*n);
 293300         if( q<m ) makeheap(p+q, m-q, 2*n+1);
 294301 }
 295302 
 296303 select(int m)
 297304 {
 298305         register int l,i,k;
 299306 
 300307         for(i=1; ; i*=2)
 301308                 if( (i-1) > m ) break;
 302309         l = ((k = i/2 - 1) + 1)/2;
 303310         return( l + (m-k < l ? m-k : l));
 304311 }
 305312 
 306313 walkheap(int start, int limit)
 307314 {
 308315         int label;
 309316 
 310317         if( start > limit ) return;
 311318         printf("        cmpl    r0,$%d\n"heapsw[start].sval);
 312319         printf("        jeql    " LBLFMT "\n", heapsw[start].slab);
 313320         if( (2*start) > limit ) {
 314321                 printf("        jbr     " LBLFMT "\n", heapsw[0].slab);
 315322                 return;
 316323         }
 317324         if( (2*start+1) <= limit ) {
 318325                 label = getlab();
 319326                 printf("        jgtr    " LBLFMT "\n", label);
 320327         } else
 321328                 printf("        jgtr    " LBLFMT "\n", heapsw[0].slab);
 322329         walkheap( 2*start, limit);
 323330         if( (2*start+1) <= limit ) {
 324331                 deflab1(label);
 325332                 walkheap( 2*start+1, limit);
 326333         }
 327334 }
 328335 #endif
 329336 
 330337 /*
 331338  * Called with a function call with arguments as argument.
 332339  * This is done early in buildtree() and only done once.
 333340  */
 334341 NODE *
 335342 funcode(NODE *p)
 336343 {
 337344         NODE *r, *l;
 338345 
 339346         /* Fix function call arguments. On vax, just add funarg */
 340347         for (r = p->n_right; r->n_op == CM; r = r->n_left) {
 341348                 if (r->n_right->n_op != STARG) {
 342349                         r->n_right = intprom(r->n_right);
 343350                         r->n_right = block(FUNARG, r->n_right, NIL,
 344351                             r->n_right->n_type, r->n_right->n_df,
 345352                             r->n_right->n_ap);
 346353                 }
 347354         }
 348355         if (r->n_op != STARG) {
 349356                 l = talloc();
 350357                 *l = *r;
 351358                 r->n_op = FUNARG;
 352359                 r->n_left = l;
 353360                 r->n_left = intprom(r->n_left);
 354361                 r->n_type = r->n_left->n_type;
 355362         }
 356363         return p;
 357364 }
 358365 
 359366 /*
 360367  * Generate the builtin code for FFS.
 361368  */
 362369 NODE *
 363370 builtin_ffs(const struct bitable *bt, NODE *a)
 364371 {
 365372         NODE *p, *q, *r;
 366373 
 367374         p = tempnode(0, bt->rt, 0, 0);
 368375         r = block(XARG, ccopy(p), NIL, INT, 0, 0);
 369376         r->n_name = "=&r";
 370377         q = block(XARG, a, NIL, INT, 0, 0);
 371378         q->n_name = "g";
 372379         q = block(CM, r, q, INT, 0, 0);
 373380         q = block(XASM, q, block(ICON, 0, 0, STRTY, 0, 0), INT, 0, 0);
 374381         q->n_name = "ffs $0,$32,%1,%0;bneq 1f;mnegl $1,%0;1:;incl %0";
 375382         p = block(COMOP, q, p, bt->rt, 0, 0);
 376383         return p;
 377384 }
 378385 
 379386 NODE
 380387 builtin_ffsl(const struct bitable *bt, NODE *a)
 381388 {      
 382389         return builtin_ffs(bt, a);
 383390 }
 384391 
 385392 NODE
 386393 builtin_ffsll(const struct bitable *bt, NODE *a)
 387394 {
 388395         cerror("builtin_ffsll unimplemented");
 389396         return NIL;
 390397 }
 391398 
 392399 NODE *
 393400 builtin_return_address(const struct bitable *bt, NODE *a)
 394401 {
 395402         NODE *f;
 396403 
 397404         if (a->n_op != ICON)
 398405                 goto bad;
 399406 
 400407         if (a->n_lval != 0)
 401408                 werror("unsupported argument");
 402409 
 403410         tfree(a);
 404411 
 405412         f = block(REG, NIL, NIL, INCREF(PTR+CHAR), 0, 0);
 406413         regno(f) = FPREG;
 407414         f = block(UMUL,
 408415                 block(PLUS, f,
 409416                     bcon(16), INCREF(PTR+CHAR), 0, 0), NIL, PTR+CHAR, 0, 0);
 410417         f = makety(f, PTR+VOID, 0, 0, 0);
 411418 
 412419         return f;
 413420 bad:
 414421         uerror("bad argument to __builtin_return_address");
 415422         return bcon(0);
 416423 }
 417424 
 418425 NODE *
 419426 builtin_frame_address(const struct bitable *bt, NODE *a)
 420427 {
 421428         int nframes;
 422429         NODE *f;
 423430 
 424431         if (a->n_op != ICON)
 425432                 goto bad;
 426433 
 427434         nframes = a->n_lval;
 428435 
 429436         tfree(a);
 430437 
 431438         f = block(REG, NIL, NIL, PTR+CHAR, 0, 0);
 432439         regno(f) = FPREG;
 433440 
 434441         while (nframes--) {
 435442                 f = block(UMUL,
 436443                         block(PLUS, f,
 437444                             bcon(12), INCREF(PTR+CHAR), 0, 0),
 438445                                 NIL, PTR+CHAR, 0, 0);
 439446                 f = makety(f, PTR+CHAR, 0, 0, 0);
 440447         }
 441448 
 442449         return f;
 443450 bad:
 444451         uerror("bad argument to __builtin_frame_address");
 445452         return bcon(0);
 446453 }
 447454 
 448455 /*
 449456  * Return "canonical frame address".
 450457  */
 451458 NODE *
 452459 builtin_cfa(const struct bitable *bt, NODE *a)
 453460 {
 454461         uerror("missing builtin_cfa");
 455462         return bcon(0);
 456463 }
 457464 
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-11-01 00:48 +0100