Blob
1 #include <u.h>2 #include <libc.h>3 #include <bio.h>4 #include <ctype.h>5 #include <mach.h>6 #define Extern extern7 #include "acid.h"9 static int fsize[256];11 static void12 initfsize(void)13 {14 fsize['A'] = 4;15 fsize['B'] = 4;16 fsize['C'] = 1;17 fsize['D'] = 4;18 fsize['F'] = 8;19 fsize['G'] = 8;20 fsize['O'] = 4;21 fsize['Q'] = 4;22 fsize['R'] = 4;23 fsize['S'] = 4;24 fsize['U'] = 4;25 fsize['V'] = 8;26 fsize['X'] = 4;27 fsize['Y'] = 8;28 fsize['W'] = 8;29 fsize['Z'] = 8;30 fsize['a'] = 4;31 fsize['b'] = 1;32 fsize['c'] = 1;33 fsize['d'] = 2;34 fsize['f'] = 4;35 fsize['g'] = 4;36 fsize['o'] = 2;37 fsize['q'] = 2;38 fsize['r'] = 2;39 fsize['s'] = 4;40 fsize['u'] = 2;41 fsize['x'] = 2;42 }44 int45 fmtsize(Value *v)46 {47 int ret;49 switch(v->store.fmt) {50 default:51 return fsize[(unsigned char)v->store.fmt];52 case 'i':53 case 'I':54 if(v->type != TINT || mach == 0)55 error("no size for i fmt pointer ++/--");56 ret = (*mach->instsize)(symmap, v->store.u.ival);57 if(ret < 0) {58 ret = (*mach->instsize)(symmap, v->store.u.ival);59 if(ret < 0)60 error("%r");61 }62 return ret;63 }64 }66 Lsym*67 chklval(Node *lp)68 {69 Node res;70 Lsym *s;72 if(lp->op == ONAME)73 return lp->sym;75 if(lp->op == OCALL){76 s = chklval(lp->left);77 if(strcmp(s->name, "var") == 078 && (lp->builtin || s->proc == 0)){79 if(lp->right == 0)80 error("var(string): arg count");81 expr(lp->right, &res);82 if(res.type != TSTRING)83 error("var(string): arg type");84 return mkvar(res.store.u.string->string);85 }86 }87 error("need l-value");88 return nil;89 }91 void92 olist(Node *n, Node *res)93 {94 expr(n->left, res);95 expr(n->right, res);96 }98 void99 oeval(Node *n, Node *res)100 {101 expr(n->left, res);102 if(res->type != TCODE)103 error("bad type for eval");104 expr(res->store.u.cc, res);105 }107 void108 ocast(Node *n, Node *res)109 {110 if(n->sym->lt == 0)111 error("%s is not a complex type", n->sym->name);113 expr(n->left, res);114 res->store.comt = n->sym->lt;115 res->store.fmt = 'a';116 }118 void119 oindm(Node *n, Node *res)120 {121 Map *m;122 Node l;124 m = cormap;125 if(m == 0)126 m = symmap;127 expr(n->left, &l);128 switch(l.type){129 default:130 error("bad type for *");131 case TINT:132 if(m == 0)133 error("no map for *");134 indir(m, l.store.u.ival, l.store.fmt, res);135 res->store.comt = l.store.comt;136 break;137 case TREG:138 indirreg(correg, l.store.u.reg.name, l.store.fmt, res);139 res->store.comt = l.store.comt;140 break;141 case TCON:142 *res = *l.store.u.con;143 res->store.comt = l.store.comt;144 break;145 }146 }148 void149 oindc(Node *n, Node *res)150 {151 Map *m;152 Node l;154 m = symmap;155 if(m == 0)156 m = cormap;157 expr(n->left, &l);158 if(l.type != TINT)159 error("bad type for @");160 if(m == 0)161 error("no map for @");162 indir(m, l.store.u.ival, l.store.fmt, res);163 res->store.comt = l.store.comt;164 }166 void167 oframe(Node *n, Node *res)168 {169 char *p;170 Node *lp;171 u64int ival;172 Frtype *f;174 p = n->sym->name;175 while(*p && *p == '$')176 p++;177 lp = n->left;178 if(localaddr(cormap, acidregs, p, lp->sym->name, &ival) < 0)179 error("colon: %r");181 res->store.u.ival = ival;182 res->op = OCONST;183 res->store.fmt = 'X';184 res->type = TINT;186 /* Try and set comt */187 for(f = n->sym->local; f; f = f->next) {188 if(f->var == lp->sym) {189 res->store.comt = f->type;190 res->store.fmt = 'a';191 break;192 }193 }194 }196 void197 oindex(Node *n, Node *res)198 {199 Node l, r;201 expr(n->left, &l);202 expr(n->right, &r);204 if(r.type != TINT)205 error("bad type for []");207 switch(l.type) {208 default:209 error("lhs[] has bad type");210 case TINT:211 indir(cormap, l.store.u.ival+(r.store.u.ival*fsize[(unsigned char)l.store.fmt]), l.store.fmt, res);212 res->store.comt = l.store.comt;213 res->store.fmt = l.store.fmt;214 break;215 case TLIST:216 nthelem(l.store.u.l, r.store.u.ival, res);217 break;218 case TSTRING:219 res->store.u.ival = 0;220 if(r.store.u.ival >= 0 && r.store.u.ival < l.store.u.string->len) {221 int xx8; /* to get around bug in vc */222 xx8 = r.store.u.ival;223 res->store.u.ival = l.store.u.string->string[xx8];224 }225 res->op = OCONST;226 res->type = TINT;227 res->store.fmt = 'c';228 break;229 }230 }232 void233 oappend(Node *n, Node *res)234 {235 Node r, l;237 expr(n->left, &l);238 expr(n->right, &r);239 if(l.type != TLIST)240 error("must append to list");241 append(res, &l, &r);242 }244 void245 odelete(Node *n, Node *res)246 {247 Node l, r;249 expr(n->left, &l);250 expr(n->right, &r);251 if(l.type != TLIST)252 error("must delete from list");253 if(r.type != TINT)254 error("delete index must be integer");256 delete(l.store.u.l, r.store.u.ival, res);257 }259 void260 ohead(Node *n, Node *res)261 {262 Node l;264 expr(n->left, &l);265 if(l.type != TLIST)266 error("head needs list");267 res->op = OCONST;268 if(l.store.u.l) {269 res->type = l.store.u.l->type;270 res->store = l.store.u.l->store;271 }272 else {273 res->type = TLIST;274 res->store.u.l = 0;275 }276 }278 void279 otail(Node *n, Node *res)280 {281 Node l;283 expr(n->left, &l);284 if(l.type != TLIST)285 error("tail needs list");286 res->op = OCONST;287 res->type = TLIST;288 if(l.store.u.l)289 res->store.u.l = l.store.u.l->next;290 else291 res->store.u.l = 0;292 }294 void295 oconst(Node *n, Node *res)296 {297 res->op = OCONST;298 res->type = n->type;299 res->store = n->store;300 res->store.comt = n->store.comt;301 }303 void304 oname(Node *n, Node *res)305 {306 Value *v;308 v = n->sym->v;309 if(v->set == 0)310 error("%s used but not set", n->sym->name);311 res->op = OCONST;312 res->type = v->type;313 res->store = v->store;314 res->store.comt = v->store.comt;315 }317 void318 octruct(Node *n, Node *res)319 {320 res->op = OCONST;321 res->type = TLIST;322 res->store.u.l = construct(n->left);323 }325 void326 oasgn(Node *n, Node *res)327 {328 Node *lp, r;329 Node aes;330 Value *v;332 lp = n->left;333 switch(lp->op) {334 case OINDM:335 expr(lp->left, &aes);336 if(aes.type == TREG)337 windirreg(correg, aes.store.u.reg.name, n->right, res);338 else339 windir(cormap, aes, n->right, res);340 break;341 case OINDC:342 expr(lp->left, &aes);343 windir(symmap, aes, n->right, res);344 break;345 default:346 v = chklval(lp)->v;347 expr(n->right, &r);348 v->set = 1;349 v->type = r.type;350 v->store = r.store;351 res->op = OCONST;352 res->type = v->type;353 res->store = v->store;354 res->store.comt = v->store.comt;355 }356 }358 void359 oadd(Node *n, Node *res)360 {361 Node l, r;363 expr(n->left, &l);364 expr(n->right, &r);365 res->store.fmt = l.store.fmt;366 res->op = OCONST;367 res->type = TFLOAT;368 switch(l.type) {369 default:370 error("bad lhs type +");371 case TINT:372 switch(r.type) {373 case TINT:374 res->type = TINT;375 res->store.u.ival = l.store.u.ival+r.store.u.ival;376 break;377 case TFLOAT:378 res->store.u.fval = l.store.u.ival+r.store.u.fval;379 break;380 default:381 error("bad rhs type +");382 }383 break;384 case TFLOAT:385 switch(r.type) {386 case TINT:387 res->store.u.fval = l.store.u.fval+r.store.u.ival;388 break;389 case TFLOAT:390 res->store.u.fval = l.store.u.fval+r.store.u.fval;391 break;392 default:393 error("bad rhs type +");394 }395 break;396 case TSTRING:397 if(r.type == TSTRING) {398 res->type = TSTRING;399 res->store.fmt = 's';400 res->store.u.string = stradd(l.store.u.string, r.store.u.string);401 break;402 }403 error("bad rhs for +");404 case TLIST:405 res->type = TLIST;406 switch(r.type) {407 case TLIST:408 res->store.u.l = addlist(l.store.u.l, r.store.u.l);409 break;410 default:411 r.left = 0;412 r.right = 0;413 res->store.u.l = addlist(l.store.u.l, construct(&r));414 break;415 }416 }417 }419 void420 osub(Node *n, Node *res)421 {422 Node l, r;424 expr(n->left, &l);425 expr(n->right, &r);426 res->store.fmt = l.store.fmt;427 res->op = OCONST;428 res->type = TFLOAT;429 switch(l.type) {430 default:431 error("bad lhs type -");432 case TINT:433 switch(r.type) {434 case TINT:435 res->type = TINT;436 res->store.u.ival = l.store.u.ival-r.store.u.ival;437 break;438 case TFLOAT:439 res->store.u.fval = l.store.u.ival-r.store.u.fval;440 break;441 default:442 error("bad rhs type -");443 }444 break;445 case TFLOAT:446 switch(r.type) {447 case TINT:448 res->store.u.fval = l.store.u.fval-r.store.u.ival;449 break;450 case TFLOAT:451 res->store.u.fval = l.store.u.fval-r.store.u.fval;452 break;453 default:454 error("bad rhs type -");455 }456 break;457 }458 }460 void461 omul(Node *n, Node *res)462 {463 Node l, r;465 expr(n->left, &l);466 expr(n->right, &r);467 res->store.fmt = l.store.fmt;468 res->op = OCONST;469 res->type = TFLOAT;470 switch(l.type) {471 default:472 error("bad lhs type *");473 case TINT:474 switch(r.type) {475 case TINT:476 res->type = TINT;477 res->store.u.ival = l.store.u.ival*r.store.u.ival;478 break;479 case TFLOAT:480 res->store.u.fval = l.store.u.ival*r.store.u.fval;481 break;482 default:483 error("bad rhs type *");484 }485 break;486 case TFLOAT:487 switch(r.type) {488 case TINT:489 res->store.u.fval = l.store.u.fval*r.store.u.ival;490 break;491 case TFLOAT:492 res->store.u.fval = l.store.u.fval*r.store.u.fval;493 break;494 default:495 error("bad rhs type *");496 }497 break;498 }499 }501 void502 odiv(Node *n, Node *res)503 {504 Node l, r;506 expr(n->left, &l);507 expr(n->right, &r);508 res->store.fmt = l.store.fmt;509 res->op = OCONST;510 res->type = TFLOAT;511 switch(l.type) {512 default:513 error("bad lhs type /");514 case TINT:515 switch(r.type) {516 case TINT:517 res->type = TINT;518 if(r.store.u.ival == 0)519 error("zero divide");520 res->store.u.ival = l.store.u.ival/r.store.u.ival;521 break;522 case TFLOAT:523 if(r.store.u.fval == 0)524 error("zero divide");525 res->store.u.fval = l.store.u.ival/r.store.u.fval;526 break;527 default:528 error("bad rhs type /");529 }530 break;531 case TFLOAT:532 switch(r.type) {533 case TINT:534 res->store.u.fval = l.store.u.fval/r.store.u.ival;535 break;536 case TFLOAT:537 res->store.u.fval = l.store.u.fval/r.store.u.fval;538 break;539 default:540 error("bad rhs type /");541 }542 break;543 }544 }546 void547 omod(Node *n, Node *res)548 {549 Node l, r;551 expr(n->left, &l);552 expr(n->right, &r);553 res->store.fmt = l.store.fmt;554 res->op = OCONST;555 res->type = TINT;556 if(l.type != TINT || r.type != TINT)557 error("bad expr type %");558 res->store.u.ival = l.store.u.ival%r.store.u.ival;559 }561 void562 olsh(Node *n, Node *res)563 {564 Node l, r;566 expr(n->left, &l);567 expr(n->right, &r);568 res->store.fmt = l.store.fmt;569 res->op = OCONST;570 res->type = TINT;571 if(l.type != TINT || r.type != TINT)572 error("bad expr type <<");573 res->store.u.ival = l.store.u.ival<<r.store.u.ival;574 }576 void577 orsh(Node *n, Node *res)578 {579 Node l, r;581 expr(n->left, &l);582 expr(n->right, &r);583 res->store.fmt = l.store.fmt;584 res->op = OCONST;585 res->type = TINT;586 if(l.type != TINT || r.type != TINT)587 error("bad expr type >>");588 res->store.u.ival = (unsigned)l.store.u.ival>>r.store.u.ival;589 }591 void592 olt(Node *n, Node *res)593 {594 Node l, r;596 expr(n->left, &l);597 expr(n->right, &r);599 res->store.fmt = l.store.fmt;600 res->op = OCONST;601 res->type = TINT;602 switch(l.type) {603 default:604 error("bad lhs type <");605 case TINT:606 switch(r.type) {607 case TINT:608 res->store.u.ival = l.store.u.ival < r.store.u.ival;609 break;610 case TFLOAT:611 res->store.u.ival = l.store.u.ival < r.store.u.fval;612 break;613 default:614 error("bad rhs type <");615 }616 break;617 case TFLOAT:618 switch(r.type) {619 case TINT:620 res->store.u.ival = l.store.u.fval < r.store.u.ival;621 break;622 case TFLOAT:623 res->store.u.ival = l.store.u.fval < r.store.u.fval;624 break;625 default:626 error("bad rhs type <");627 }628 break;629 }630 }632 void633 ogt(Node *n, Node *res)634 {635 Node l, r;637 expr(n->left, &l);638 expr(n->right, &r);639 res->store.fmt = 'D';640 res->op = OCONST;641 res->type = TINT;642 switch(l.type) {643 default:644 error("bad lhs type >");645 case TINT:646 switch(r.type) {647 case TINT:648 res->store.u.ival = l.store.u.ival > r.store.u.ival;649 break;650 case TFLOAT:651 res->store.u.ival = l.store.u.ival > r.store.u.fval;652 break;653 default:654 error("bad rhs type >");655 }656 break;657 case TFLOAT:658 switch(r.type) {659 case TINT:660 res->store.u.ival = l.store.u.fval > r.store.u.ival;661 break;662 case TFLOAT:663 res->store.u.ival = l.store.u.fval > r.store.u.fval;664 break;665 default:666 error("bad rhs type >");667 }668 break;669 }670 }672 void673 oleq(Node *n, Node *res)674 {675 Node l, r;677 expr(n->left, &l);678 expr(n->right, &r);679 res->store.fmt = 'D';680 res->op = OCONST;681 res->type = TINT;682 switch(l.type) {683 default:684 error("bad expr type <=");685 case TINT:686 switch(r.type) {687 case TINT:688 res->store.u.ival = l.store.u.ival <= r.store.u.ival;689 break;690 case TFLOAT:691 res->store.u.ival = l.store.u.ival <= r.store.u.fval;692 break;693 default:694 error("bad expr type <=");695 }696 break;697 case TFLOAT:698 switch(r.type) {699 case TINT:700 res->store.u.ival = l.store.u.fval <= r.store.u.ival;701 break;702 case TFLOAT:703 res->store.u.ival = l.store.u.fval <= r.store.u.fval;704 break;705 default:706 error("bad expr type <=");707 }708 break;709 }710 }712 void713 ogeq(Node *n, Node *res)714 {715 Node l, r;717 expr(n->left, &l);718 expr(n->right, &r);719 res->store.fmt = 'D';720 res->op = OCONST;721 res->type = TINT;722 switch(l.type) {723 default:724 error("bad lhs type >=");725 case TINT:726 switch(r.type) {727 case TINT:728 res->store.u.ival = l.store.u.ival >= r.store.u.ival;729 break;730 case TFLOAT:731 res->store.u.ival = l.store.u.ival >= r.store.u.fval;732 break;733 default:734 error("bad rhs type >=");735 }736 break;737 case TFLOAT:738 switch(r.type) {739 case TINT:740 res->store.u.ival = l.store.u.fval >= r.store.u.ival;741 break;742 case TFLOAT:743 res->store.u.ival = l.store.u.fval >= r.store.u.fval;744 break;745 default:746 error("bad rhs type >=");747 }748 break;749 }750 }752 void753 oeq(Node *n, Node *res)754 {755 Node l, r;757 expr(n->left, &l);758 expr(n->right, &r);759 res->store.fmt = 'D';760 res->op = OCONST;761 res->type = TINT;762 res->store.u.ival = 0;763 switch(l.type) {764 default:765 break;766 case TINT:767 switch(r.type) {768 case TINT:769 res->store.u.ival = l.store.u.ival == r.store.u.ival;770 break;771 case TFLOAT:772 res->store.u.ival = l.store.u.ival == r.store.u.fval;773 break;774 default:775 break;776 }777 break;778 case TFLOAT:779 switch(r.type) {780 case TINT:781 res->store.u.ival = l.store.u.fval == r.store.u.ival;782 break;783 case TFLOAT:784 res->store.u.ival = l.store.u.fval == r.store.u.fval;785 break;786 default:787 break;788 }789 break;790 case TSTRING:791 if(r.type == TSTRING) {792 res->store.u.ival = scmp(r.store.u.string, l.store.u.string);793 break;794 }795 break;796 case TLIST:797 if(r.type == TLIST) {798 res->store.u.ival = listcmp(l.store.u.l, r.store.u.l);799 break;800 }801 break;802 }803 if(n->op == ONEQ)804 res->store.u.ival = !res->store.u.ival;805 }808 void809 oland(Node *n, Node *res)810 {811 Node l, r;813 expr(n->left, &l);814 expr(n->right, &r);815 res->store.fmt = l.store.fmt;816 res->op = OCONST;817 res->type = TINT;818 if(l.type != TINT || r.type != TINT)819 error("bad expr type &");820 res->store.u.ival = l.store.u.ival&r.store.u.ival;821 }823 void824 oxor(Node *n, Node *res)825 {826 Node l, r;828 expr(n->left, &l);829 expr(n->right, &r);830 res->store.fmt = l.store.fmt;831 res->op = OCONST;832 res->type = TINT;833 if(l.type != TINT || r.type != TINT)834 error("bad expr type ^");835 res->store.u.ival = l.store.u.ival^r.store.u.ival;836 }838 void839 olor(Node *n, Node *res)840 {841 Node l, r;843 expr(n->left, &l);844 expr(n->right, &r);845 res->store.fmt = l.store.fmt;846 res->op = OCONST;847 res->type = TINT;848 if(l.type != TINT || r.type != TINT)849 error("bad expr type |");850 res->store.u.ival = l.store.u.ival|r.store.u.ival;851 }853 void854 ocand(Node *n, Node *res)855 {856 Node l, r;858 res->store.fmt = 'D';859 res->op = OCONST;860 res->type = TINT;861 res->store.u.ival = 0;862 expr(n->left, &l);863 res->store.fmt = l.store.fmt;864 if(bool(&l) == 0)865 return;866 expr(n->right, &r);867 if(bool(&r) == 0)868 return;869 res->store.u.ival = 1;870 }872 void873 onot(Node *n, Node *res)874 {875 Node l;877 res->op = OCONST;878 res->type = TINT;879 res->store.u.ival = 0;880 expr(n->left, &l);881 if(bool(&l) == 0)882 res->store.u.ival = 1;883 }885 void886 ocor(Node *n, Node *res)887 {888 Node l, r;890 res->op = OCONST;891 res->type = TINT;892 res->store.u.ival = 0;893 expr(n->left, &l);894 if(bool(&l)) {895 res->store.u.ival = 1;896 return;897 }898 expr(n->right, &r);899 if(bool(&r)) {900 res->store.u.ival = 1;901 return;902 }903 }905 void906 oeinc(Node *n, Node *res)907 {908 Value *v;910 v = chklval(n->left)->v;911 res->op = OCONST;912 res->type = v->type;913 switch(v->type) {914 case TINT:915 if(n->op == OEDEC)916 v->store.u.ival -= fmtsize(v);917 else918 v->store.u.ival += fmtsize(v);919 break;920 case TFLOAT:921 if(n->op == OEDEC)922 v->store.u.fval--;923 else924 v->store.u.fval++;925 break;926 default:927 error("bad type for pre --/++");928 }929 res->store = v->store;930 }932 void933 opinc(Node *n, Node *res)934 {935 Value *v;937 v = chklval(n->left)->v;938 res->op = OCONST;939 res->type = v->type;940 res->store = v->store;941 switch(v->type) {942 case TINT:943 if(n->op == OPDEC)944 v->store.u.ival -= fmtsize(v);945 else946 v->store.u.ival += fmtsize(v);947 break;948 case TFLOAT:949 if(n->op == OPDEC)950 v->store.u.fval--;951 else952 v->store.u.fval++;953 break;954 default:955 error("bad type for post --/++");956 }957 }959 void960 ocall(Node *n, Node *res)961 {962 Lsym *s;963 Rplace *rsav;965 res->op = OCONST; /* Default return value */966 res->type = TLIST;967 res->store.u.l = 0;969 s = chklval(n->left);970 if(n->builtin && !s->builtin){971 error("no builtin %s", s->name);972 return;973 }974 if(s->builtin && (n->builtin || s->proc == 0)) {975 (*s->builtin)(res, n->right);976 return;977 }978 if(s->proc == 0)979 error("no function %s", s->name);981 rsav = ret;982 call(s->name, n->right, s->proc->left, s->proc->right, res);983 ret = rsav;984 }986 void987 ofmt(Node *n, Node *res)988 {989 expr(n->left, res);990 res->store.fmt = n->right->store.u.ival;991 }993 void994 ouplus(Node *n, Node *res)995 {996 expr(n->left, res);997 }999 void1000 owhat(Node *n, Node *res)1001 {1002 res->op = OCONST; /* Default return value */1003 res->type = TLIST;1004 res->store.u.l = 0;1005 whatis(n->sym);1006 }1008 void (*expop[NUMO])(Node*, Node*);1010 static void1011 initexpop(void)1012 {1013 expop[ONAME] = oname;1014 expop[OCONST] = oconst;1015 expop[OMUL] = omul;1016 expop[ODIV] = odiv;1017 expop[OMOD] = omod;1018 expop[OADD] = oadd;1019 expop[OSUB] = osub;1020 expop[ORSH] = orsh;1021 expop[OLSH] = olsh;1022 expop[OLT] = olt;1023 expop[OGT] = ogt;1024 expop[OLEQ] = oleq;1025 expop[OGEQ] = ogeq;1026 expop[OEQ] = oeq;1027 expop[ONEQ] = oeq;1028 expop[OLAND] = oland;1029 expop[OXOR] = oxor;1030 expop[OLOR] = olor;1031 expop[OCAND] = ocand;1032 expop[OCOR] = ocor;1033 expop[OASGN] = oasgn;1034 expop[OINDM] = oindm;1035 expop[OEDEC] = oeinc;1036 expop[OEINC] = oeinc;1037 expop[OPINC] = opinc;1038 expop[OPDEC] = opinc;1039 expop[ONOT] = onot;1040 expop[OIF] = 0;1041 expop[ODO] = 0;1042 expop[OLIST] = olist;1043 expop[OCALL] = ocall;1044 expop[OCTRUCT] = octruct;1045 expop[OWHILE] =0;1046 expop[OELSE] = 0;1047 expop[OHEAD] = ohead;1048 expop[OTAIL] = otail;1049 expop[OAPPEND] = oappend;1050 expop[ORET] = 0;1051 expop[OINDEX] =oindex;1052 expop[OINDC] = oindc;1053 expop[ODOT] = odot;1054 expop[OLOCAL] =0;1055 expop[OFRAME] = oframe;1056 expop[OCOMPLEX] =0;1057 expop[ODELETE] = odelete;1058 expop[OCAST] = ocast;1059 expop[OFMT] = ofmt;1060 expop[OEVAL] = oeval;1061 expop[OWHAT] = owhat;1062 expop[OUPLUS] = ouplus;1063 }1065 void1066 initexpr(void)1067 {1068 initfsize();1069 initexpop();1070 }1072 int1073 acidregsrw(Regs *r, char *name, u64int *u, int isr)1074 {1075 Lsym *l;1076 Value *v;1077 Node *n;1078 u64int addr;1080 if(!isr){1081 werrstr("cannot write registers");1082 return -1;1083 }1084 USED(r);1085 l = look(name);1086 if(l == nil){1087 werrstr("register %s not found", name);1088 return -1;1089 }1090 v = l->v;1091 switch(v->type){1092 default:1093 werrstr("*%s: bad type", name);1094 return -1;1095 case TREG:1096 if(correg == nil){1097 werrstr("*%s: register %s not mapped", name, v->store.u.reg);1098 return -1;1099 }1100 return rget(correg, v->store.u.reg.name, u);1101 case TCON:1102 n = v->store.u.con;1103 if(n->op != OCONST || n->type != TINT){1104 werrstr("*%s: bad register constant", name);1105 return -1;1106 }1107 *u = n->store.u.ival;1108 return 0;1109 case TINT:1110 if(cormap == nil){1111 werrstr("*%s: core not mapped", name);1112 return -1;1113 }1114 addr = v->store.u.ival;1115 /* XXX should use format to determine size */1116 if(geta(cormap, addr, u) < 0)1117 return -1;1118 return 0;1119 }1120 }