URI:
       tloc.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tloc.c (4331B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include <mach.h>
            5 
            6 int
            7 locfmt(Fmt *fmt)
            8 {
            9         Loc l;
           10 
           11         l = va_arg(fmt->args, Loc);
           12         switch(l.type){
           13         default:
           14                 return fmtprint(fmt, "<loc%d>", l.type);
           15         case LCONST:
           16                 return fmtprint(fmt, "0x%lux", l.addr);
           17         case LADDR:
           18                 return fmtprint(fmt, "*0x%lux", l.addr);
           19         case LOFFSET:
           20                 return fmtprint(fmt, "%ld(%s)", l.offset, l.reg);
           21         case LREG:
           22                 return fmtprint(fmt, "%s", l.reg);
           23         }
           24 }
           25 
           26 int
           27 loccmp(Loc *a, Loc *b)
           28 {
           29         int i;
           30 
           31         if(a->type < b->type)
           32                 return -1;
           33         if(a->type > b->type)
           34                 return 1;
           35         switch(a->type){
           36         default:
           37                 return 0;
           38         case LADDR:
           39                 if(a->addr < b->addr)
           40                         return -1;
           41                 if(a->addr > b->addr)
           42                         return 1;
           43                 return 0;
           44         case LOFFSET:
           45                 i = strcmp(a->reg, b->reg);
           46                 if(i != 0)
           47                         return i;
           48                 if(a->offset < b->offset)
           49                         return -1;
           50                 if(a->offset > b->offset)
           51                         return 1;
           52                 return 0;
           53         case LREG:
           54                 return strcmp(a->reg, b->reg);
           55         }
           56 }
           57 
           58 int
           59 lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
           60 {
           61         if(locsimplify(map, regs, loc, &loc) < 0)
           62                 return -1;
           63         if(loc.type == LADDR)
           64                 return get1(map, loc.addr, a, n);
           65         /* could do more here - i'm lazy */
           66         werrstr("bad location for lget1");
           67         return -1;
           68 }
           69 
           70 int
           71 lget2(Map *map, Regs *regs, Loc loc, u16int *u)
           72 {
           73         u64int ul;
           74 
           75         if(locsimplify(map, regs, loc, &loc) < 0)
           76                 return -1;
           77         if(loc.type == LADDR)
           78                 return get2(map, loc.addr, u);
           79         if(loc.type == LCONST){
           80                 *u = loc.addr;
           81                 return 0;
           82         }
           83         if(loc.type == LREG){
           84                 if(rget(regs, loc.reg, &ul) < 0)
           85                         return -1;
           86                 *u = ul;
           87                 return 0;
           88         }
           89         werrstr("bad location for lget2");
           90         return -1;
           91 }
           92 
           93 int
           94 lget4(Map *map, Regs *regs, Loc loc, u32int *u)
           95 {
           96         u64int ul;
           97 
           98         if(locsimplify(map, regs, loc, &loc) < 0)
           99                 return -1;
          100         if(loc.type == LADDR)
          101                 return get4(map, loc.addr, u);
          102         if(loc.type == LCONST){
          103                 *u = loc.addr;
          104                 return 0;
          105         }
          106         if(loc.type == LREG){
          107                 if(rget(regs, loc.reg, &ul) < 0)
          108                         return -1;
          109                 *u = ul;
          110                 return 0;
          111         }
          112         werrstr("bad location for lget4");
          113         return -1;
          114 }
          115 
          116 int
          117 lgeta(Map *map, Regs *regs, Loc loc, u64int *u)
          118 {
          119         u32int v;
          120 
          121         if(machcpu == &machamd64)
          122                 return lget8(map, regs, loc, u);
          123         if(lget4(map, regs, loc, &v) < 0)
          124                 return -1;
          125         *u = v;
          126         return 4;
          127 }
          128 
          129 int
          130 lget8(Map *map, Regs *regs, Loc loc, u64int *u)
          131 {
          132         u64int ul;
          133 
          134         if(locsimplify(map, regs, loc, &loc) < 0)
          135                 return -1;
          136         if(loc.type == LADDR)
          137                 return get8(map, loc.addr, u);
          138         if(loc.type == LCONST){
          139                 *u = loc.addr;
          140                 return 0;
          141         }
          142         if(loc.type == LREG){
          143                 if(rget(regs, loc.reg, &ul) < 0)
          144                         return -1;
          145                 *u = ul;
          146                 return 0;
          147         }
          148         werrstr("bad location for lget8");
          149         return -1;
          150 }
          151 
          152 int
          153 lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
          154 {
          155         if(locsimplify(map, regs, loc, &loc) < 0)
          156                 return -1;
          157         if(loc.type == LADDR)
          158                 return put1(map, loc.addr, a, n);
          159         /* could do more here - i'm lazy */
          160         werrstr("bad location for lput1");
          161         return -1;
          162 }
          163 
          164 int
          165 lput2(Map *map, Regs *regs, Loc loc, u16int u)
          166 {
          167         if(locsimplify(map, regs, loc, &loc) < 0)
          168                 return -1;
          169         if(loc.type == LADDR)
          170                 return put2(map, loc.addr, u);
          171         if(loc.type == LREG)
          172                 return rput(regs, loc.reg, u);
          173         werrstr("bad location for lput2");
          174         return -1;
          175 }
          176 
          177 int
          178 lput4(Map *map, Regs *regs, Loc loc, u32int u)
          179 {
          180         if(locsimplify(map, regs, loc, &loc) < 0)
          181                 return -1;
          182         if(loc.type == LADDR)
          183                 return put4(map, loc.addr, u);
          184         if(loc.type == LREG)
          185                 return rput(regs, loc.reg, u);
          186         werrstr("bad location for lput4");
          187         return -1;
          188 }
          189 
          190 int
          191 lput8(Map *map, Regs *regs, Loc loc, u64int u)
          192 {
          193         if(locsimplify(map, regs, loc, &loc) < 0)
          194                 return -1;
          195         if(loc.type == LADDR)
          196                 return put8(map, loc.addr, u);
          197         if(loc.type == LREG)
          198                 return rput(regs, loc.reg, u);
          199         werrstr("bad location for lput8");
          200         return -1;
          201 }
          202 
          203 static Loc zl;
          204 
          205 Loc
          206 locaddr(u64int addr)
          207 {
          208         Loc l;
          209 
          210         l = zl;
          211         l.type = LADDR;
          212         l.addr = addr;
          213         return l;
          214 }
          215 
          216 Loc
          217 locindir(char *reg, long offset)
          218 {
          219         Loc l;
          220 
          221         l = zl;
          222         l.type = LOFFSET;
          223         l.reg = reg;
          224         l.offset = offset;
          225         l.addr = 0;        /* SHUT UP GCC 4.0 */
          226         return l;
          227 }
          228 
          229 Loc
          230 locconst(u64int con)
          231 {
          232         Loc l;
          233 
          234         l = zl;
          235         l.type = LCONST;
          236         l.addr = con;
          237         return l;
          238 }
          239 
          240 Loc
          241 locnone(void)
          242 {
          243         Loc l;
          244 
          245         l = zl;
          246         l.type = LNONE;
          247         return l;
          248 }
          249 
          250 Loc
          251 locreg(char *reg)
          252 {
          253         Loc l;
          254 
          255         l = zl;
          256         l.type = LREG;
          257         l.reg = reg;
          258         return l;
          259 }
          260 
          261 int
          262 locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc)
          263 {
          264         u64int u;
          265 
          266         if(loc.type == LOFFSET){
          267                 if(rget(regs, loc.reg, &u) < 0)
          268                         return -1;
          269                 *newloc = locaddr(u + loc.offset);
          270         }else
          271                 *newloc = loc;
          272         return 0;
          273 }