17dd7cddfSDavid du Colombier #include "l.h"
27dd7cddfSDavid du Colombier
37dd7cddfSDavid du Colombier long OFFSET;
47dd7cddfSDavid du Colombier
559cc4ca5SDavid du Colombier static Prog *PP;
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier long
entryvalue(void)87dd7cddfSDavid du Colombier entryvalue(void)
97dd7cddfSDavid du Colombier {
107dd7cddfSDavid du Colombier char *a;
117dd7cddfSDavid du Colombier Sym *s;
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier a = INITENTRY;
147dd7cddfSDavid du Colombier if(*a >= '0' && *a <= '9')
157dd7cddfSDavid du Colombier return atolwhex(a);
167dd7cddfSDavid du Colombier s = lookup(a, 0);
177dd7cddfSDavid du Colombier if(s->type == 0)
187dd7cddfSDavid du Colombier return INITTEXT;
199a747e4fSDavid du Colombier switch(s->type) {
209a747e4fSDavid du Colombier case STEXT:
219a747e4fSDavid du Colombier case SLEAF:
229a747e4fSDavid du Colombier break;
239a747e4fSDavid du Colombier case SDATA:
24375daca8SDavid du Colombier if(dlm)
259a747e4fSDavid du Colombier return s->value+INITDAT;
269a747e4fSDavid du Colombier default:
277dd7cddfSDavid du Colombier diag("entry not text: %s", s->name);
289a747e4fSDavid du Colombier }
297dd7cddfSDavid du Colombier return s->value;
307dd7cddfSDavid du Colombier }
317dd7cddfSDavid du Colombier
327dd7cddfSDavid du Colombier void
asmb(void)337dd7cddfSDavid du Colombier asmb(void)
347dd7cddfSDavid du Colombier {
357dd7cddfSDavid du Colombier Prog *p;
369a747e4fSDavid du Colombier long t, etext;
377dd7cddfSDavid du Colombier Optab *o;
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier if(debug['v'])
407dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f asm\n", cputime());
417dd7cddfSDavid du Colombier Bflush(&bso);
427dd7cddfSDavid du Colombier OFFSET = HEADR;
437dd7cddfSDavid du Colombier seek(cout, OFFSET, 0);
447dd7cddfSDavid du Colombier pc = INITTEXT;
457dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) {
467dd7cddfSDavid du Colombier if(p->as == ATEXT) {
477dd7cddfSDavid du Colombier curtext = p;
487dd7cddfSDavid du Colombier autosize = p->to.offset + 4;
497dd7cddfSDavid du Colombier }
507dd7cddfSDavid du Colombier if(p->pc != pc) {
517dd7cddfSDavid du Colombier diag("phase error %lux sb %lux",
527dd7cddfSDavid du Colombier p->pc, pc);
537dd7cddfSDavid du Colombier if(!debug['a'])
547dd7cddfSDavid du Colombier prasm(curp);
557dd7cddfSDavid du Colombier pc = p->pc;
567dd7cddfSDavid du Colombier }
577dd7cddfSDavid du Colombier curp = p;
587dd7cddfSDavid du Colombier o = oplook(p); /* could probably avoid this call */
597dd7cddfSDavid du Colombier asmout(p, o);
607dd7cddfSDavid du Colombier pc += o->size;
617dd7cddfSDavid du Colombier }
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier if(debug['a'])
647dd7cddfSDavid du Colombier Bprint(&bso, "\n");
657dd7cddfSDavid du Colombier Bflush(&bso);
667dd7cddfSDavid du Colombier cflush();
677dd7cddfSDavid du Colombier
689a747e4fSDavid du Colombier /* output strings in text segment */
699a747e4fSDavid du Colombier etext = INITTEXT + textsize;
709a747e4fSDavid du Colombier for(t = pc; t < etext; t += sizeof(buf)-100) {
719a747e4fSDavid du Colombier if(etext-t > sizeof(buf)-100)
729a747e4fSDavid du Colombier datblk(t, sizeof(buf)-100, 1);
739a747e4fSDavid du Colombier else
749a747e4fSDavid du Colombier datblk(t, etext-t, 1);
759a747e4fSDavid du Colombier }
769a747e4fSDavid du Colombier
777dd7cddfSDavid du Colombier curtext = P;
787dd7cddfSDavid du Colombier switch(HEADTYPE) {
7959cc4ca5SDavid du Colombier case 0:
807dd7cddfSDavid du Colombier case 1:
817dd7cddfSDavid du Colombier case 2:
8259cc4ca5SDavid du Colombier case 5:
83b94bb474SDavid du Colombier case 7:
847dd7cddfSDavid du Colombier OFFSET = HEADR+textsize;
857dd7cddfSDavid du Colombier seek(cout, OFFSET, 0);
867dd7cddfSDavid du Colombier break;
877dd7cddfSDavid du Colombier case 3:
886f95e41dSDavid du Colombier case 6: /* no header, padded segments */
897dd7cddfSDavid du Colombier OFFSET = rnd(HEADR+textsize, 4096);
907dd7cddfSDavid du Colombier seek(cout, OFFSET, 0);
917dd7cddfSDavid du Colombier break;
927dd7cddfSDavid du Colombier }
93375daca8SDavid du Colombier if(dlm){
94375daca8SDavid du Colombier char buf[8];
95375daca8SDavid du Colombier
96375daca8SDavid du Colombier write(cout, buf, INITDAT-textsize);
97375daca8SDavid du Colombier textsize = INITDAT;
98375daca8SDavid du Colombier }
997dd7cddfSDavid du Colombier for(t = 0; t < datsize; t += sizeof(buf)-100) {
1007dd7cddfSDavid du Colombier if(datsize-t > sizeof(buf)-100)
1019a747e4fSDavid du Colombier datblk(t, sizeof(buf)-100, 0);
1027dd7cddfSDavid du Colombier else
1039a747e4fSDavid du Colombier datblk(t, datsize-t, 0);
1047dd7cddfSDavid du Colombier }
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier symsize = 0;
1077dd7cddfSDavid du Colombier lcsize = 0;
1087dd7cddfSDavid du Colombier if(!debug['s']) {
1097dd7cddfSDavid du Colombier if(debug['v'])
1107dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f sym\n", cputime());
1117dd7cddfSDavid du Colombier Bflush(&bso);
1127dd7cddfSDavid du Colombier switch(HEADTYPE) {
11359cc4ca5SDavid du Colombier case 0:
1147dd7cddfSDavid du Colombier case 1:
11559cc4ca5SDavid du Colombier case 4:
11659cc4ca5SDavid du Colombier case 5:
1177dd7cddfSDavid du Colombier debug['s'] = 1;
1187dd7cddfSDavid du Colombier break;
1197dd7cddfSDavid du Colombier case 2:
1207dd7cddfSDavid du Colombier OFFSET = HEADR+textsize+datsize;
1217dd7cddfSDavid du Colombier seek(cout, OFFSET, 0);
1227dd7cddfSDavid du Colombier break;
1237dd7cddfSDavid du Colombier case 3:
1246f95e41dSDavid du Colombier case 6: /* no header, padded segments */
1257dd7cddfSDavid du Colombier OFFSET += rnd(datsize, 4096);
1267dd7cddfSDavid du Colombier seek(cout, OFFSET, 0);
1277dd7cddfSDavid du Colombier break;
128b94bb474SDavid du Colombier case 7:
129b94bb474SDavid du Colombier break;
1307dd7cddfSDavid du Colombier }
1317dd7cddfSDavid du Colombier if(!debug['s'])
1327dd7cddfSDavid du Colombier asmsym();
1337dd7cddfSDavid du Colombier if(debug['v'])
1347dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f pc\n", cputime());
1357dd7cddfSDavid du Colombier Bflush(&bso);
1367dd7cddfSDavid du Colombier if(!debug['s'])
1377dd7cddfSDavid du Colombier asmlc();
138375daca8SDavid du Colombier if(dlm)
139375daca8SDavid du Colombier asmdyn();
140375daca8SDavid du Colombier cflush();
141375daca8SDavid du Colombier }
142375daca8SDavid du Colombier else if(dlm){
143375daca8SDavid du Colombier seek(cout, HEADR+textsize+datsize, 0);
144375daca8SDavid du Colombier asmdyn();
1457dd7cddfSDavid du Colombier cflush();
1467dd7cddfSDavid du Colombier }
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier if(debug['v'])
1497dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f header\n", cputime());
1507dd7cddfSDavid du Colombier Bflush(&bso);
1517dd7cddfSDavid du Colombier OFFSET = 0;
1527dd7cddfSDavid du Colombier seek(cout, OFFSET, 0);
1537dd7cddfSDavid du Colombier switch(HEADTYPE) {
15459cc4ca5SDavid du Colombier case 0: /* no header */
1556f95e41dSDavid du Colombier case 6: /* no header, padded segments */
15659cc4ca5SDavid du Colombier break;
1577dd7cddfSDavid du Colombier case 1: /* aif for risc os */
1587dd7cddfSDavid du Colombier lputl(0xe1a00000); /* NOP - decompress code */
1597dd7cddfSDavid du Colombier lputl(0xe1a00000); /* NOP - relocation code */
1607dd7cddfSDavid du Colombier lputl(0xeb000000 + 12); /* BL - zero init code */
1617dd7cddfSDavid du Colombier lputl(0xeb000000 +
1627dd7cddfSDavid du Colombier (entryvalue()
1637dd7cddfSDavid du Colombier - INITTEXT
1647dd7cddfSDavid du Colombier + HEADR
1657dd7cddfSDavid du Colombier - 12
1667dd7cddfSDavid du Colombier - 8) / 4); /* BL - entry code */
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier lputl(0xef000011); /* SWI - exit code */
1697dd7cddfSDavid du Colombier lputl(textsize+HEADR); /* text size */
1707dd7cddfSDavid du Colombier lputl(datsize); /* data size */
1717dd7cddfSDavid du Colombier lputl(0); /* sym size */
1727dd7cddfSDavid du Colombier
1737dd7cddfSDavid du Colombier lputl(bsssize); /* bss size */
1747dd7cddfSDavid du Colombier lputl(0); /* sym type */
1757dd7cddfSDavid du Colombier lputl(INITTEXT-HEADR); /* text addr */
1767dd7cddfSDavid du Colombier lputl(0); /* workspace - ignored */
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier lputl(32); /* addr mode / data addr flag */
1797dd7cddfSDavid du Colombier lputl(0); /* data addr */
1807dd7cddfSDavid du Colombier for(t=0; t<2; t++)
1817dd7cddfSDavid du Colombier lputl(0); /* reserved */
1827dd7cddfSDavid du Colombier
1837dd7cddfSDavid du Colombier for(t=0; t<15; t++)
1847dd7cddfSDavid du Colombier lputl(0xe1a00000); /* NOP - zero init code */
1857dd7cddfSDavid du Colombier lputl(0xe1a0f00e); /* B (R14) - zero init return */
1867dd7cddfSDavid du Colombier break;
1877dd7cddfSDavid du Colombier case 2: /* plan 9 */
188375daca8SDavid du Colombier if(dlm)
189375daca8SDavid du Colombier lput(0x80000000|0x647); /* magic */
190375daca8SDavid du Colombier else
1917dd7cddfSDavid du Colombier lput(0x647); /* magic */
1927dd7cddfSDavid du Colombier lput(textsize); /* sizes */
1937dd7cddfSDavid du Colombier lput(datsize);
1947dd7cddfSDavid du Colombier lput(bsssize);
1957dd7cddfSDavid du Colombier lput(symsize); /* nsyms */
1967dd7cddfSDavid du Colombier lput(entryvalue()); /* va of entry */
1977dd7cddfSDavid du Colombier lput(0L);
1987dd7cddfSDavid du Colombier lput(lcsize);
1997dd7cddfSDavid du Colombier break;
2007dd7cddfSDavid du Colombier case 3: /* boot for NetBSD */
2017dd7cddfSDavid du Colombier lput((143<<16)|0413); /* magic */
2027dd7cddfSDavid du Colombier lputl(rnd(HEADR+textsize, 4096));
2037dd7cddfSDavid du Colombier lputl(rnd(datsize, 4096));
2047dd7cddfSDavid du Colombier lputl(bsssize);
2057dd7cddfSDavid du Colombier lputl(symsize); /* nsyms */
2067dd7cddfSDavid du Colombier lputl(entryvalue()); /* va of entry */
2077dd7cddfSDavid du Colombier lputl(0L);
2087dd7cddfSDavid du Colombier lputl(0L);
2097dd7cddfSDavid du Colombier break;
21059cc4ca5SDavid du Colombier case 4: /* boot for IXP1200 */
21159cc4ca5SDavid du Colombier break;
21259cc4ca5SDavid du Colombier case 5: /* boot for ipaq */
21359cc4ca5SDavid du Colombier lputl(0xe3300000); /* nop */
21459cc4ca5SDavid du Colombier lputl(0xe3300000); /* nop */
21559cc4ca5SDavid du Colombier lputl(0xe3300000); /* nop */
21659cc4ca5SDavid du Colombier lputl(0xe3300000); /* nop */
21759cc4ca5SDavid du Colombier break;
218b94bb474SDavid du Colombier case 7: /* elf */
219*8153b942SDavid du Colombier debug['S'] = 1; /* symbol table */
220*8153b942SDavid du Colombier elf32(ARM, ELFDATA2LSB, 0, nil);
221b94bb474SDavid du Colombier break;
2227dd7cddfSDavid du Colombier }
2237dd7cddfSDavid du Colombier cflush();
2247dd7cddfSDavid du Colombier }
2257dd7cddfSDavid du Colombier
2267dd7cddfSDavid du Colombier void
strnput(char * s,int n)2277dd7cddfSDavid du Colombier strnput(char *s, int n)
2287dd7cddfSDavid du Colombier {
2297dd7cddfSDavid du Colombier for(; *s; s++){
23059cc4ca5SDavid du Colombier cput(*s);
2317dd7cddfSDavid du Colombier n--;
2327dd7cddfSDavid du Colombier }
2337dd7cddfSDavid du Colombier for(; n > 0; n--)
23459cc4ca5SDavid du Colombier cput(0);
23559cc4ca5SDavid du Colombier }
23659cc4ca5SDavid du Colombier
23759cc4ca5SDavid du Colombier void
cput(int c)23859cc4ca5SDavid du Colombier cput(int c)
23959cc4ca5SDavid du Colombier {
24059cc4ca5SDavid du Colombier cbp[0] = c;
24159cc4ca5SDavid du Colombier cbp++;
24259cc4ca5SDavid du Colombier cbc--;
24359cc4ca5SDavid du Colombier if(cbc <= 0)
24459cc4ca5SDavid du Colombier cflush();
2457dd7cddfSDavid du Colombier }
2467dd7cddfSDavid du Colombier
2477dd7cddfSDavid du Colombier void
wput(long l)248375daca8SDavid du Colombier wput(long l)
249375daca8SDavid du Colombier {
250375daca8SDavid du Colombier
251375daca8SDavid du Colombier cbp[0] = l>>8;
252375daca8SDavid du Colombier cbp[1] = l;
253375daca8SDavid du Colombier cbp += 2;
254375daca8SDavid du Colombier cbc -= 2;
255375daca8SDavid du Colombier if(cbc <= 0)
256375daca8SDavid du Colombier cflush();
257375daca8SDavid du Colombier }
258375daca8SDavid du Colombier
259375daca8SDavid du Colombier void
wputl(long l)260*8153b942SDavid du Colombier wputl(long l)
261*8153b942SDavid du Colombier {
262*8153b942SDavid du Colombier
263*8153b942SDavid du Colombier cbp[0] = l;
264*8153b942SDavid du Colombier cbp[1] = l>>8;
265*8153b942SDavid du Colombier cbp += 2;
266*8153b942SDavid du Colombier cbc -= 2;
267*8153b942SDavid du Colombier if(cbc <= 0)
268*8153b942SDavid du Colombier cflush();
269*8153b942SDavid du Colombier }
270*8153b942SDavid du Colombier
271*8153b942SDavid du Colombier void
lput(long l)2727dd7cddfSDavid du Colombier lput(long l)
2737dd7cddfSDavid du Colombier {
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier cbp[0] = l>>24;
2767dd7cddfSDavid du Colombier cbp[1] = l>>16;
2777dd7cddfSDavid du Colombier cbp[2] = l>>8;
2787dd7cddfSDavid du Colombier cbp[3] = l;
2797dd7cddfSDavid du Colombier cbp += 4;
2807dd7cddfSDavid du Colombier cbc -= 4;
2817dd7cddfSDavid du Colombier if(cbc <= 0)
2827dd7cddfSDavid du Colombier cflush();
2837dd7cddfSDavid du Colombier }
2847dd7cddfSDavid du Colombier
2857dd7cddfSDavid du Colombier void
lputl(long l)2867dd7cddfSDavid du Colombier lputl(long l)
2877dd7cddfSDavid du Colombier {
2887dd7cddfSDavid du Colombier
2897dd7cddfSDavid du Colombier cbp[3] = l>>24;
2907dd7cddfSDavid du Colombier cbp[2] = l>>16;
2917dd7cddfSDavid du Colombier cbp[1] = l>>8;
2927dd7cddfSDavid du Colombier cbp[0] = l;
2937dd7cddfSDavid du Colombier cbp += 4;
2947dd7cddfSDavid du Colombier cbc -= 4;
2957dd7cddfSDavid du Colombier if(cbc <= 0)
2967dd7cddfSDavid du Colombier cflush();
2977dd7cddfSDavid du Colombier }
2987dd7cddfSDavid du Colombier
2997dd7cddfSDavid du Colombier void
llput(vlong v)300*8153b942SDavid du Colombier llput(vlong v)
301*8153b942SDavid du Colombier {
302*8153b942SDavid du Colombier lput(v>>32);
303*8153b942SDavid du Colombier lput(v);
304*8153b942SDavid du Colombier }
305*8153b942SDavid du Colombier
306*8153b942SDavid du Colombier void
llputl(vlong v)307*8153b942SDavid du Colombier llputl(vlong v)
308*8153b942SDavid du Colombier {
309*8153b942SDavid du Colombier lputl(v);
310*8153b942SDavid du Colombier lputl(v>>32);
311*8153b942SDavid du Colombier }
312*8153b942SDavid du Colombier
313*8153b942SDavid du Colombier void
cflush(void)3147dd7cddfSDavid du Colombier cflush(void)
3157dd7cddfSDavid du Colombier {
3167dd7cddfSDavid du Colombier int n;
3177dd7cddfSDavid du Colombier
3187dd7cddfSDavid du Colombier n = sizeof(buf.cbuf) - cbc;
3197dd7cddfSDavid du Colombier if(n)
3207dd7cddfSDavid du Colombier write(cout, buf.cbuf, n);
3217dd7cddfSDavid du Colombier cbp = buf.cbuf;
3227dd7cddfSDavid du Colombier cbc = sizeof(buf.cbuf);
3237dd7cddfSDavid du Colombier }
3247dd7cddfSDavid du Colombier
3257dd7cddfSDavid du Colombier void
nopstat(char * f,Count * c)3267dd7cddfSDavid du Colombier nopstat(char *f, Count *c)
3277dd7cddfSDavid du Colombier {
3287dd7cddfSDavid du Colombier if(c->outof)
3297dd7cddfSDavid du Colombier Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
3307dd7cddfSDavid du Colombier c->outof - c->count, c->outof,
3317dd7cddfSDavid du Colombier (double)(c->outof - c->count)/c->outof);
3327dd7cddfSDavid du Colombier }
3337dd7cddfSDavid du Colombier
3347dd7cddfSDavid du Colombier void
asmsym(void)3357dd7cddfSDavid du Colombier asmsym(void)
3367dd7cddfSDavid du Colombier {
3377dd7cddfSDavid du Colombier Prog *p;
3387dd7cddfSDavid du Colombier Auto *a;
3397dd7cddfSDavid du Colombier Sym *s;
3407dd7cddfSDavid du Colombier int h;
3417dd7cddfSDavid du Colombier
3427dd7cddfSDavid du Colombier s = lookup("etext", 0);
3437dd7cddfSDavid du Colombier if(s->type == STEXT)
3447dd7cddfSDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
3457dd7cddfSDavid du Colombier
3467dd7cddfSDavid du Colombier for(h=0; h<NHASH; h++)
3477dd7cddfSDavid du Colombier for(s=hash[h]; s!=S; s=s->link)
3487dd7cddfSDavid du Colombier switch(s->type) {
3497dd7cddfSDavid du Colombier case SCONST:
3507dd7cddfSDavid du Colombier putsymb(s->name, 'D', s->value, s->version);
3517dd7cddfSDavid du Colombier continue;
3527dd7cddfSDavid du Colombier
3537dd7cddfSDavid du Colombier case SDATA:
3547dd7cddfSDavid du Colombier putsymb(s->name, 'D', s->value+INITDAT, s->version);
3557dd7cddfSDavid du Colombier continue;
3567dd7cddfSDavid du Colombier
3577dd7cddfSDavid du Colombier case SBSS:
3587dd7cddfSDavid du Colombier putsymb(s->name, 'B', s->value+INITDAT, s->version);
3597dd7cddfSDavid du Colombier continue;
3607dd7cddfSDavid du Colombier
3619a747e4fSDavid du Colombier case SSTRING:
3629a747e4fSDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
3639a747e4fSDavid du Colombier continue;
3649a747e4fSDavid du Colombier
3657dd7cddfSDavid du Colombier case SFILE:
3667dd7cddfSDavid du Colombier putsymb(s->name, 'f', s->value, s->version);
3677dd7cddfSDavid du Colombier continue;
3687dd7cddfSDavid du Colombier }
3697dd7cddfSDavid du Colombier
3707dd7cddfSDavid du Colombier for(p=textp; p!=P; p=p->cond) {
3717dd7cddfSDavid du Colombier s = p->from.sym;
3727dd7cddfSDavid du Colombier if(s->type != STEXT && s->type != SLEAF)
3737dd7cddfSDavid du Colombier continue;
3747dd7cddfSDavid du Colombier
3757dd7cddfSDavid du Colombier /* filenames first */
3767dd7cddfSDavid du Colombier for(a=p->to.autom; a; a=a->link)
3777dd7cddfSDavid du Colombier if(a->type == D_FILE)
3787dd7cddfSDavid du Colombier putsymb(a->asym->name, 'z', a->aoffset, 0);
3797dd7cddfSDavid du Colombier else
3807dd7cddfSDavid du Colombier if(a->type == D_FILE1)
3817dd7cddfSDavid du Colombier putsymb(a->asym->name, 'Z', a->aoffset, 0);
3827dd7cddfSDavid du Colombier
3837dd7cddfSDavid du Colombier if(s->type == STEXT)
3847dd7cddfSDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
3857dd7cddfSDavid du Colombier else
3867dd7cddfSDavid du Colombier putsymb(s->name, 'L', s->value, s->version);
3877dd7cddfSDavid du Colombier
3887dd7cddfSDavid du Colombier /* frame, auto and param after */
3897dd7cddfSDavid du Colombier putsymb(".frame", 'm', p->to.offset+4, 0);
3907dd7cddfSDavid du Colombier for(a=p->to.autom; a; a=a->link)
3917dd7cddfSDavid du Colombier if(a->type == D_AUTO)
3927dd7cddfSDavid du Colombier putsymb(a->asym->name, 'a', -a->aoffset, 0);
3937dd7cddfSDavid du Colombier else
3947dd7cddfSDavid du Colombier if(a->type == D_PARAM)
3957dd7cddfSDavid du Colombier putsymb(a->asym->name, 'p', a->aoffset, 0);
3967dd7cddfSDavid du Colombier }
3977dd7cddfSDavid du Colombier if(debug['v'] || debug['n'])
3987dd7cddfSDavid du Colombier Bprint(&bso, "symsize = %lud\n", symsize);
3997dd7cddfSDavid du Colombier Bflush(&bso);
4007dd7cddfSDavid du Colombier }
4017dd7cddfSDavid du Colombier
4027dd7cddfSDavid du Colombier void
putsymb(char * s,int t,long v,int ver)4037dd7cddfSDavid du Colombier putsymb(char *s, int t, long v, int ver)
4047dd7cddfSDavid du Colombier {
4057dd7cddfSDavid du Colombier int i, f;
4067dd7cddfSDavid du Colombier
4077dd7cddfSDavid du Colombier if(t == 'f')
4087dd7cddfSDavid du Colombier s++;
4097dd7cddfSDavid du Colombier lput(v);
4107dd7cddfSDavid du Colombier if(ver)
4117dd7cddfSDavid du Colombier t += 'a' - 'A';
41259cc4ca5SDavid du Colombier cput(t+0x80); /* 0x80 is variable length */
4137dd7cddfSDavid du Colombier
4147dd7cddfSDavid du Colombier if(t == 'Z' || t == 'z') {
41559cc4ca5SDavid du Colombier cput(s[0]);
4167dd7cddfSDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
41759cc4ca5SDavid du Colombier cput(s[i]);
41859cc4ca5SDavid du Colombier cput(s[i+1]);
4197dd7cddfSDavid du Colombier }
42059cc4ca5SDavid du Colombier cput(0);
42159cc4ca5SDavid du Colombier cput(0);
4227dd7cddfSDavid du Colombier i++;
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier else {
4257dd7cddfSDavid du Colombier for(i=0; s[i]; i++)
42659cc4ca5SDavid du Colombier cput(s[i]);
42759cc4ca5SDavid du Colombier cput(0);
4287dd7cddfSDavid du Colombier }
4297dd7cddfSDavid du Colombier symsize += 4 + 1 + i + 1;
4307dd7cddfSDavid du Colombier
4317dd7cddfSDavid du Colombier if(debug['n']) {
4327dd7cddfSDavid du Colombier if(t == 'z' || t == 'Z') {
4337dd7cddfSDavid du Colombier Bprint(&bso, "%c %.8lux ", t, v);
4347dd7cddfSDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
4357dd7cddfSDavid du Colombier f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
4367dd7cddfSDavid du Colombier Bprint(&bso, "/%x", f);
4377dd7cddfSDavid du Colombier }
4387dd7cddfSDavid du Colombier Bprint(&bso, "\n");
4397dd7cddfSDavid du Colombier return;
4407dd7cddfSDavid du Colombier }
4417dd7cddfSDavid du Colombier if(ver)
4427dd7cddfSDavid du Colombier Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
4437dd7cddfSDavid du Colombier else
4447dd7cddfSDavid du Colombier Bprint(&bso, "%c %.8lux %s\n", t, v, s);
4457dd7cddfSDavid du Colombier }
4467dd7cddfSDavid du Colombier }
4477dd7cddfSDavid du Colombier
4487dd7cddfSDavid du Colombier #define MINLC 4
4497dd7cddfSDavid du Colombier void
asmlc(void)4507dd7cddfSDavid du Colombier asmlc(void)
4517dd7cddfSDavid du Colombier {
4527dd7cddfSDavid du Colombier long oldpc, oldlc;
4537dd7cddfSDavid du Colombier Prog *p;
4547dd7cddfSDavid du Colombier long v, s;
4557dd7cddfSDavid du Colombier
4567dd7cddfSDavid du Colombier oldpc = INITTEXT;
4577dd7cddfSDavid du Colombier oldlc = 0;
4587dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) {
4597dd7cddfSDavid du Colombier if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
4607dd7cddfSDavid du Colombier if(p->as == ATEXT)
4617dd7cddfSDavid du Colombier curtext = p;
462b87cd620SDavid du Colombier if(debug['V'])
4637dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
4647dd7cddfSDavid du Colombier p->pc, p);
4657dd7cddfSDavid du Colombier continue;
4667dd7cddfSDavid du Colombier }
467b87cd620SDavid du Colombier if(debug['V'])
4687dd7cddfSDavid du Colombier Bprint(&bso, "\t\t%6ld", lcsize);
4697dd7cddfSDavid du Colombier v = (p->pc - oldpc) / MINLC;
4707dd7cddfSDavid du Colombier while(v) {
4717dd7cddfSDavid du Colombier s = 127;
4727dd7cddfSDavid du Colombier if(v < 127)
4737dd7cddfSDavid du Colombier s = v;
47459cc4ca5SDavid du Colombier cput(s+128); /* 129-255 +pc */
475b87cd620SDavid du Colombier if(debug['V'])
4767dd7cddfSDavid du Colombier Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
4777dd7cddfSDavid du Colombier v -= s;
4787dd7cddfSDavid du Colombier lcsize++;
4797dd7cddfSDavid du Colombier }
4807dd7cddfSDavid du Colombier s = p->line - oldlc;
4817dd7cddfSDavid du Colombier oldlc = p->line;
4827dd7cddfSDavid du Colombier oldpc = p->pc + MINLC;
4837dd7cddfSDavid du Colombier if(s > 64 || s < -64) {
48459cc4ca5SDavid du Colombier cput(0); /* 0 vv +lc */
48559cc4ca5SDavid du Colombier cput(s>>24);
48659cc4ca5SDavid du Colombier cput(s>>16);
48759cc4ca5SDavid du Colombier cput(s>>8);
48859cc4ca5SDavid du Colombier cput(s);
489b87cd620SDavid du Colombier if(debug['V']) {
4907dd7cddfSDavid du Colombier if(s > 0)
4917dd7cddfSDavid du Colombier Bprint(&bso, " lc+%ld(%d,%ld)\n",
4927dd7cddfSDavid du Colombier s, 0, s);
4937dd7cddfSDavid du Colombier else
4947dd7cddfSDavid du Colombier Bprint(&bso, " lc%ld(%d,%ld)\n",
4957dd7cddfSDavid du Colombier s, 0, s);
4967dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
4977dd7cddfSDavid du Colombier p->pc, p);
4987dd7cddfSDavid du Colombier }
4997dd7cddfSDavid du Colombier lcsize += 5;
5007dd7cddfSDavid du Colombier continue;
5017dd7cddfSDavid du Colombier }
5027dd7cddfSDavid du Colombier if(s > 0) {
50359cc4ca5SDavid du Colombier cput(0+s); /* 1-64 +lc */
504b87cd620SDavid du Colombier if(debug['V']) {
5057dd7cddfSDavid du Colombier Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
5067dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
5077dd7cddfSDavid du Colombier p->pc, p);
5087dd7cddfSDavid du Colombier }
5097dd7cddfSDavid du Colombier } else {
51059cc4ca5SDavid du Colombier cput(64-s); /* 65-128 -lc */
511b87cd620SDavid du Colombier if(debug['V']) {
5127dd7cddfSDavid du Colombier Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
5137dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
5147dd7cddfSDavid du Colombier p->pc, p);
5157dd7cddfSDavid du Colombier }
5167dd7cddfSDavid du Colombier }
5177dd7cddfSDavid du Colombier lcsize++;
5187dd7cddfSDavid du Colombier }
5197dd7cddfSDavid du Colombier while(lcsize & 1) {
5207dd7cddfSDavid du Colombier s = 129;
52159cc4ca5SDavid du Colombier cput(s);
5227dd7cddfSDavid du Colombier lcsize++;
5237dd7cddfSDavid du Colombier }
524b87cd620SDavid du Colombier if(debug['v'] || debug['V'])
5257dd7cddfSDavid du Colombier Bprint(&bso, "lcsize = %ld\n", lcsize);
5267dd7cddfSDavid du Colombier Bflush(&bso);
5277dd7cddfSDavid du Colombier }
5287dd7cddfSDavid du Colombier
5297dd7cddfSDavid du Colombier void
datblk(long s,long n,int str)5309a747e4fSDavid du Colombier datblk(long s, long n, int str)
5317dd7cddfSDavid du Colombier {
5329a747e4fSDavid du Colombier Sym *v;
5337dd7cddfSDavid du Colombier Prog *p;
5347dd7cddfSDavid du Colombier char *cast;
5359a747e4fSDavid du Colombier long a, l, fl, j, d;
5367dd7cddfSDavid du Colombier int i, c;
5377dd7cddfSDavid du Colombier
5387dd7cddfSDavid du Colombier memset(buf.dbuf, 0, n+100);
5397dd7cddfSDavid du Colombier for(p = datap; p != P; p = p->link) {
5409a747e4fSDavid du Colombier if(str != (p->from.sym->type == SSTRING))
5419a747e4fSDavid du Colombier continue;
5427dd7cddfSDavid du Colombier curp = p;
5439a747e4fSDavid du Colombier a = p->from.sym->value + p->from.offset;
5449a747e4fSDavid du Colombier l = a - s;
5457dd7cddfSDavid du Colombier c = p->reg;
5467dd7cddfSDavid du Colombier i = 0;
5477dd7cddfSDavid du Colombier if(l < 0) {
5487dd7cddfSDavid du Colombier if(l+c <= 0)
5497dd7cddfSDavid du Colombier continue;
5507dd7cddfSDavid du Colombier while(l < 0) {
5517dd7cddfSDavid du Colombier l++;
5527dd7cddfSDavid du Colombier i++;
5537dd7cddfSDavid du Colombier }
5547dd7cddfSDavid du Colombier }
5557dd7cddfSDavid du Colombier if(l >= n)
5567dd7cddfSDavid du Colombier continue;
5577dd7cddfSDavid du Colombier if(p->as != AINIT && p->as != ADYNT) {
5587dd7cddfSDavid du Colombier for(j=l+(c-i)-1; j>=l; j--)
5597dd7cddfSDavid du Colombier if(buf.dbuf[j]) {
5607dd7cddfSDavid du Colombier print("%P\n", p);
5617dd7cddfSDavid du Colombier diag("multiple initialization");
5627dd7cddfSDavid du Colombier break;
5637dd7cddfSDavid du Colombier }
5647dd7cddfSDavid du Colombier }
5657dd7cddfSDavid du Colombier switch(p->to.type) {
5667dd7cddfSDavid du Colombier default:
5677dd7cddfSDavid du Colombier diag("unknown mode in initialization%P", p);
5687dd7cddfSDavid du Colombier break;
5697dd7cddfSDavid du Colombier
5707dd7cddfSDavid du Colombier case D_FCONST:
5717dd7cddfSDavid du Colombier switch(c) {
5727dd7cddfSDavid du Colombier default:
5737dd7cddfSDavid du Colombier case 4:
5747dd7cddfSDavid du Colombier fl = ieeedtof(p->to.ieee);
5757dd7cddfSDavid du Colombier cast = (char*)&fl;
5767dd7cddfSDavid du Colombier for(; i<c; i++) {
5777dd7cddfSDavid du Colombier buf.dbuf[l] = cast[fnuxi4[i]];
5787dd7cddfSDavid du Colombier l++;
5797dd7cddfSDavid du Colombier }
5807dd7cddfSDavid du Colombier break;
5817dd7cddfSDavid du Colombier case 8:
5827dd7cddfSDavid du Colombier cast = (char*)p->to.ieee;
5837dd7cddfSDavid du Colombier for(; i<c; i++) {
5847dd7cddfSDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i]];
5857dd7cddfSDavid du Colombier l++;
5867dd7cddfSDavid du Colombier }
5877dd7cddfSDavid du Colombier break;
5887dd7cddfSDavid du Colombier }
5897dd7cddfSDavid du Colombier break;
5907dd7cddfSDavid du Colombier
5917dd7cddfSDavid du Colombier case D_SCONST:
5927dd7cddfSDavid du Colombier for(; i<c; i++) {
5937dd7cddfSDavid du Colombier buf.dbuf[l] = p->to.sval[i];
5947dd7cddfSDavid du Colombier l++;
5957dd7cddfSDavid du Colombier }
5967dd7cddfSDavid du Colombier break;
5977dd7cddfSDavid du Colombier
5987dd7cddfSDavid du Colombier case D_CONST:
5997dd7cddfSDavid du Colombier d = p->to.offset;
6009a747e4fSDavid du Colombier v = p->to.sym;
6019a747e4fSDavid du Colombier if(v) {
6029a747e4fSDavid du Colombier switch(v->type) {
603375daca8SDavid du Colombier case SUNDEF:
604375daca8SDavid du Colombier ckoff(v, d);
6059a747e4fSDavid du Colombier case STEXT:
6069a747e4fSDavid du Colombier case SLEAF:
6079a747e4fSDavid du Colombier case SSTRING:
6087dd7cddfSDavid du Colombier d += p->to.sym->value;
6099a747e4fSDavid du Colombier break;
6109a747e4fSDavid du Colombier case SDATA:
6119a747e4fSDavid du Colombier case SBSS:
6127dd7cddfSDavid du Colombier d += p->to.sym->value + INITDAT;
6139a747e4fSDavid du Colombier }
614375daca8SDavid du Colombier if(dlm)
615375daca8SDavid du Colombier dynreloc(v, a+INITDAT, 1);
6167dd7cddfSDavid du Colombier }
6177dd7cddfSDavid du Colombier cast = (char*)&d;
6187dd7cddfSDavid du Colombier switch(c) {
6197dd7cddfSDavid du Colombier default:
6207dd7cddfSDavid du Colombier diag("bad nuxi %d %d%P", c, i, curp);
6217dd7cddfSDavid du Colombier break;
6227dd7cddfSDavid du Colombier case 1:
6237dd7cddfSDavid du Colombier for(; i<c; i++) {
6247dd7cddfSDavid du Colombier buf.dbuf[l] = cast[inuxi1[i]];
6257dd7cddfSDavid du Colombier l++;
6267dd7cddfSDavid du Colombier }
6277dd7cddfSDavid du Colombier break;
6287dd7cddfSDavid du Colombier case 2:
6297dd7cddfSDavid du Colombier for(; i<c; i++) {
6307dd7cddfSDavid du Colombier buf.dbuf[l] = cast[inuxi2[i]];
6317dd7cddfSDavid du Colombier l++;
6327dd7cddfSDavid du Colombier }
6337dd7cddfSDavid du Colombier break;
6347dd7cddfSDavid du Colombier case 4:
6357dd7cddfSDavid du Colombier for(; i<c; i++) {
6367dd7cddfSDavid du Colombier buf.dbuf[l] = cast[inuxi4[i]];
6377dd7cddfSDavid du Colombier l++;
6387dd7cddfSDavid du Colombier }
6397dd7cddfSDavid du Colombier break;
6407dd7cddfSDavid du Colombier }
6417dd7cddfSDavid du Colombier break;
6427dd7cddfSDavid du Colombier }
6437dd7cddfSDavid du Colombier }
6447dd7cddfSDavid du Colombier write(cout, buf.dbuf, n);
6457dd7cddfSDavid du Colombier }
6467dd7cddfSDavid du Colombier
6477dd7cddfSDavid du Colombier void
asmout(Prog * p,Optab * o)6487dd7cddfSDavid du Colombier asmout(Prog *p, Optab *o)
6497dd7cddfSDavid du Colombier {
65059cc4ca5SDavid du Colombier long o1, o2, o3, o4, o5, o6, v;
65159cc4ca5SDavid du Colombier int r, rf, rt, rt2;
6529a747e4fSDavid du Colombier Sym *s;
6537dd7cddfSDavid du Colombier
65459cc4ca5SDavid du Colombier PP = p;
6557dd7cddfSDavid du Colombier o1 = 0;
6567dd7cddfSDavid du Colombier o2 = 0;
6577dd7cddfSDavid du Colombier o3 = 0;
6587dd7cddfSDavid du Colombier o4 = 0;
6597dd7cddfSDavid du Colombier o5 = 0;
66059cc4ca5SDavid du Colombier o6 = 0;
6617dd7cddfSDavid du Colombier switch(o->type) {
6627dd7cddfSDavid du Colombier default:
6637dd7cddfSDavid du Colombier diag("unknown asm %d", o->type);
6647dd7cddfSDavid du Colombier prasm(p);
6657dd7cddfSDavid du Colombier break;
6667dd7cddfSDavid du Colombier
6677dd7cddfSDavid du Colombier case 0: /* pseudo ops */
6687dd7cddfSDavid du Colombier break;
6697dd7cddfSDavid du Colombier
6707dd7cddfSDavid du Colombier case 1: /* op R,[R],R */
6717dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
6727dd7cddfSDavid du Colombier rf = p->from.reg;
6737dd7cddfSDavid du Colombier rt = p->to.reg;
6747dd7cddfSDavid du Colombier r = p->reg;
6757dd7cddfSDavid du Colombier if(p->to.type == D_NONE)
6767dd7cddfSDavid du Colombier rt = 0;
677530fef66SDavid du Colombier if(p->as == AMOVW || p->as == AMVN)
678530fef66SDavid du Colombier r = 0;
679530fef66SDavid du Colombier else if(r == NREG)
6807dd7cddfSDavid du Colombier r = rt;
6817dd7cddfSDavid du Colombier o1 |= rf | (r<<16) | (rt<<12);
6827dd7cddfSDavid du Colombier break;
6837dd7cddfSDavid du Colombier
68459cc4ca5SDavid du Colombier case 2: /* movbu $I,[R],R */
6857dd7cddfSDavid du Colombier aclass(&p->from);
6867dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
6877dd7cddfSDavid du Colombier o1 |= immrot(instoffset);
6887dd7cddfSDavid du Colombier rt = p->to.reg;
6897dd7cddfSDavid du Colombier r = p->reg;
6907dd7cddfSDavid du Colombier if(p->to.type == D_NONE)
6917dd7cddfSDavid du Colombier rt = 0;
692530fef66SDavid du Colombier if(p->as == AMOVW || p->as == AMVN)
693530fef66SDavid du Colombier r = 0;
694530fef66SDavid du Colombier else if(r == NREG)
6957dd7cddfSDavid du Colombier r = rt;
6967dd7cddfSDavid du Colombier o1 |= (r<<16) | (rt<<12);
6977dd7cddfSDavid du Colombier break;
6987dd7cddfSDavid du Colombier
6997dd7cddfSDavid du Colombier case 3: /* add R<<[IR],[R],R */
70059cc4ca5SDavid du Colombier mov:
7017dd7cddfSDavid du Colombier aclass(&p->from);
7027dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
7037dd7cddfSDavid du Colombier o1 |= p->from.offset;
7047dd7cddfSDavid du Colombier rt = p->to.reg;
7057dd7cddfSDavid du Colombier r = p->reg;
7067dd7cddfSDavid du Colombier if(p->to.type == D_NONE)
7077dd7cddfSDavid du Colombier rt = 0;
708530fef66SDavid du Colombier if(p->as == AMOVW || p->as == AMVN)
709530fef66SDavid du Colombier r = 0;
710530fef66SDavid du Colombier else if(r == NREG)
7117dd7cddfSDavid du Colombier r = rt;
7127dd7cddfSDavid du Colombier o1 |= (r<<16) | (rt<<12);
7137dd7cddfSDavid du Colombier break;
7147dd7cddfSDavid du Colombier
7157dd7cddfSDavid du Colombier case 4: /* add $I,[R],R */
7167dd7cddfSDavid du Colombier aclass(&p->from);
7177dd7cddfSDavid du Colombier o1 = oprrr(AADD, p->scond);
7187dd7cddfSDavid du Colombier o1 |= immrot(instoffset);
7197dd7cddfSDavid du Colombier r = p->from.reg;
7207dd7cddfSDavid du Colombier if(r == NREG)
7217dd7cddfSDavid du Colombier r = o->param;
7227dd7cddfSDavid du Colombier o1 |= r << 16;
7237dd7cddfSDavid du Colombier o1 |= p->to.reg << 12;
7247dd7cddfSDavid du Colombier break;
7257dd7cddfSDavid du Colombier
7267dd7cddfSDavid du Colombier case 5: /* bra s */
7277dd7cddfSDavid du Colombier v = -8;
7289a747e4fSDavid du Colombier if(p->cond == UP) {
7299a747e4fSDavid du Colombier s = p->to.sym;
730375daca8SDavid du Colombier if(s->type != SUNDEF)
731375daca8SDavid du Colombier diag("bad branch sym type");
732375daca8SDavid du Colombier v = (ulong)s->value >> (Roffset-2);
733375daca8SDavid du Colombier dynreloc(s, p->pc, 0);
7349a747e4fSDavid du Colombier }
7359a747e4fSDavid du Colombier else if(p->cond != P)
7367dd7cddfSDavid du Colombier v = (p->cond->pc - pc) - 8;
7377dd7cddfSDavid du Colombier o1 = opbra(p->as, p->scond);
7387dd7cddfSDavid du Colombier o1 |= (v >> 2) & 0xffffff;
7397dd7cddfSDavid du Colombier break;
7407dd7cddfSDavid du Colombier
7417dd7cddfSDavid du Colombier case 6: /* b ,O(R) -> add $O,R,PC */
7427dd7cddfSDavid du Colombier aclass(&p->to);
7437dd7cddfSDavid du Colombier o1 = oprrr(AADD, p->scond);
7447dd7cddfSDavid du Colombier o1 |= immrot(instoffset);
7457dd7cddfSDavid du Colombier o1 |= p->to.reg << 16;
7467dd7cddfSDavid du Colombier o1 |= REGPC << 12;
7477dd7cddfSDavid du Colombier break;
7487dd7cddfSDavid du Colombier
7497dd7cddfSDavid du Colombier case 7: /* bl ,O(R) -> mov PC,link; add $O,R,PC */
7507dd7cddfSDavid du Colombier aclass(&p->to);
7517dd7cddfSDavid du Colombier o1 = oprrr(AADD, p->scond);
7527dd7cddfSDavid du Colombier o1 |= immrot(0);
7537dd7cddfSDavid du Colombier o1 |= REGPC << 16;
7547dd7cddfSDavid du Colombier o1 |= REGLINK << 12;
7557dd7cddfSDavid du Colombier
7567dd7cddfSDavid du Colombier o2 = oprrr(AADD, p->scond);
7577dd7cddfSDavid du Colombier o2 |= immrot(instoffset);
7587dd7cddfSDavid du Colombier o2 |= p->to.reg << 16;
7597dd7cddfSDavid du Colombier o2 |= REGPC << 12;
7607dd7cddfSDavid du Colombier break;
7617dd7cddfSDavid du Colombier
7627dd7cddfSDavid du Colombier case 8: /* sll $c,[R],R -> mov (R<<$c),R */
7637dd7cddfSDavid du Colombier aclass(&p->from);
7647dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
7657dd7cddfSDavid du Colombier r = p->reg;
7667dd7cddfSDavid du Colombier if(r == NREG)
7677dd7cddfSDavid du Colombier r = p->to.reg;
7687dd7cddfSDavid du Colombier o1 |= r;
7697dd7cddfSDavid du Colombier o1 |= (instoffset&31) << 7;
7707dd7cddfSDavid du Colombier o1 |= p->to.reg << 12;
7717dd7cddfSDavid du Colombier break;
7727dd7cddfSDavid du Colombier
7737dd7cddfSDavid du Colombier case 9: /* sll R,[R],R -> mov (R<<R),R */
7747dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
7757dd7cddfSDavid du Colombier r = p->reg;
7767dd7cddfSDavid du Colombier if(r == NREG)
7777dd7cddfSDavid du Colombier r = p->to.reg;
7787dd7cddfSDavid du Colombier o1 |= r;
7797dd7cddfSDavid du Colombier o1 |= (p->from.reg << 8) | (1<<4);
7807dd7cddfSDavid du Colombier o1 |= p->to.reg << 12;
7817dd7cddfSDavid du Colombier break;
7827dd7cddfSDavid du Colombier
7837dd7cddfSDavid du Colombier case 10: /* swi [$con] */
7847dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
7857dd7cddfSDavid du Colombier if(p->to.type != D_NONE) {
7867dd7cddfSDavid du Colombier aclass(&p->to);
7877dd7cddfSDavid du Colombier o1 |= instoffset & 0xffffff;
7887dd7cddfSDavid du Colombier }
7897dd7cddfSDavid du Colombier break;
7907dd7cddfSDavid du Colombier
7917dd7cddfSDavid du Colombier case 11: /* word */
7929a747e4fSDavid du Colombier switch(aclass(&p->to)) {
7939a747e4fSDavid du Colombier case C_LCON:
794375daca8SDavid du Colombier if(!dlm)
7959a747e4fSDavid du Colombier break;
7969a747e4fSDavid du Colombier if(p->to.name != D_EXTERN && p->to.name != D_STATIC)
7979a747e4fSDavid du Colombier break;
7989a747e4fSDavid du Colombier case C_ADDR:
799375daca8SDavid du Colombier if(p->to.sym->type == SUNDEF)
800375daca8SDavid du Colombier ckoff(p->to.sym, p->to.offset);
801375daca8SDavid du Colombier dynreloc(p->to.sym, p->pc, 1);
8029a747e4fSDavid du Colombier }
8037dd7cddfSDavid du Colombier o1 = instoffset;
8047dd7cddfSDavid du Colombier break;
8057dd7cddfSDavid du Colombier
8067dd7cddfSDavid du Colombier case 12: /* movw $lcon, reg */
80759cc4ca5SDavid du Colombier o1 = omvl(p, &p->from, p->to.reg);
8087dd7cddfSDavid du Colombier break;
8097dd7cddfSDavid du Colombier
8107dd7cddfSDavid du Colombier case 13: /* op $lcon, [R], R */
81159cc4ca5SDavid du Colombier o1 = omvl(p, &p->from, REGTMP);
81259cc4ca5SDavid du Colombier if(!o1)
8137dd7cddfSDavid du Colombier break;
8147dd7cddfSDavid du Colombier o2 = oprrr(p->as, p->scond);
8157dd7cddfSDavid du Colombier o2 |= REGTMP;
8167dd7cddfSDavid du Colombier r = p->reg;
817530fef66SDavid du Colombier if(p->as == AMOVW || p->as == AMVN)
818530fef66SDavid du Colombier r = 0;
819530fef66SDavid du Colombier else if(r == NREG)
8207dd7cddfSDavid du Colombier r = p->to.reg;
8217dd7cddfSDavid du Colombier o2 |= r << 16;
8227dd7cddfSDavid du Colombier if(p->to.type != D_NONE)
8237dd7cddfSDavid du Colombier o2 |= p->to.reg << 12;
8247dd7cddfSDavid du Colombier break;
8257dd7cddfSDavid du Colombier
8267dd7cddfSDavid du Colombier case 14: /* movb/movbu/movh/movhu R,R */
8277dd7cddfSDavid du Colombier o1 = oprrr(ASLL, p->scond);
8287dd7cddfSDavid du Colombier
8297dd7cddfSDavid du Colombier if(p->as == AMOVBU || p->as == AMOVHU)
8307dd7cddfSDavid du Colombier o2 = oprrr(ASRL, p->scond);
8317dd7cddfSDavid du Colombier else
8327dd7cddfSDavid du Colombier o2 = oprrr(ASRA, p->scond);
8337dd7cddfSDavid du Colombier
8347dd7cddfSDavid du Colombier r = p->to.reg;
8357dd7cddfSDavid du Colombier o1 |= (p->from.reg)|(r<<12);
8367dd7cddfSDavid du Colombier o2 |= (r)|(r<<12);
8377dd7cddfSDavid du Colombier if(p->as == AMOVB || p->as == AMOVBU) {
8387dd7cddfSDavid du Colombier o1 |= (24<<7);
8397dd7cddfSDavid du Colombier o2 |= (24<<7);
8407dd7cddfSDavid du Colombier } else {
8417dd7cddfSDavid du Colombier o1 |= (16<<7);
8427dd7cddfSDavid du Colombier o2 |= (16<<7);
8437dd7cddfSDavid du Colombier }
8447dd7cddfSDavid du Colombier break;
8457dd7cddfSDavid du Colombier
8467dd7cddfSDavid du Colombier case 15: /* mul r,[r,]r */
8477dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
8487dd7cddfSDavid du Colombier rf = p->from.reg;
8497dd7cddfSDavid du Colombier rt = p->to.reg;
8507dd7cddfSDavid du Colombier r = p->reg;
8517dd7cddfSDavid du Colombier if(r == NREG)
8527dd7cddfSDavid du Colombier r = rt;
8537dd7cddfSDavid du Colombier if(rt == r) {
8547dd7cddfSDavid du Colombier r = rf;
8557dd7cddfSDavid du Colombier rf = rt;
8567dd7cddfSDavid du Colombier }
8577dd7cddfSDavid du Colombier if(0)
8587dd7cddfSDavid du Colombier if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) {
8597dd7cddfSDavid du Colombier diag("bad registers in MUL");
8607dd7cddfSDavid du Colombier prasm(p);
8617dd7cddfSDavid du Colombier }
8627dd7cddfSDavid du Colombier o1 |= (rf<<8) | r | (rt<<16);
8637dd7cddfSDavid du Colombier break;
8647dd7cddfSDavid du Colombier
8657dd7cddfSDavid du Colombier
8667dd7cddfSDavid du Colombier case 16: /* div r,[r,]r */
8677dd7cddfSDavid du Colombier o1 = 0xf << 28;
8687dd7cddfSDavid du Colombier o2 = 0;
8697dd7cddfSDavid du Colombier break;
8707dd7cddfSDavid du Colombier
87159cc4ca5SDavid du Colombier case 17:
87259cc4ca5SDavid du Colombier o1 = oprrr(p->as, p->scond);
87359cc4ca5SDavid du Colombier rf = p->from.reg;
87459cc4ca5SDavid du Colombier rt = p->to.reg;
87559cc4ca5SDavid du Colombier rt2 = p->to.offset;
87659cc4ca5SDavid du Colombier r = p->reg;
87759cc4ca5SDavid du Colombier o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12);
87859cc4ca5SDavid du Colombier break;
87959cc4ca5SDavid du Colombier
8807dd7cddfSDavid du Colombier case 20: /* mov/movb/movbu R,O(R) */
8817dd7cddfSDavid du Colombier aclass(&p->to);
8827dd7cddfSDavid du Colombier r = p->to.reg;
8837dd7cddfSDavid du Colombier if(r == NREG)
8847dd7cddfSDavid du Colombier r = o->param;
8857dd7cddfSDavid du Colombier o1 = osr(p->as, p->from.reg, instoffset, r, p->scond);
8867dd7cddfSDavid du Colombier break;
8877dd7cddfSDavid du Colombier
8887dd7cddfSDavid du Colombier case 21: /* mov/movbu O(R),R -> lr */
8897dd7cddfSDavid du Colombier aclass(&p->from);
8907dd7cddfSDavid du Colombier r = p->from.reg;
8917dd7cddfSDavid du Colombier if(r == NREG)
8927dd7cddfSDavid du Colombier r = o->param;
8937dd7cddfSDavid du Colombier o1 = olr(instoffset, r, p->to.reg, p->scond);
8947dd7cddfSDavid du Colombier if(p->as != AMOVW)
8957dd7cddfSDavid du Colombier o1 |= 1<<22;
8967dd7cddfSDavid du Colombier break;
8977dd7cddfSDavid du Colombier
8987dd7cddfSDavid du Colombier case 22: /* movb/movh/movhu O(R),R -> lr,shl,shr */
8997dd7cddfSDavid du Colombier aclass(&p->from);
9007dd7cddfSDavid du Colombier r = p->from.reg;
9017dd7cddfSDavid du Colombier if(r == NREG)
9027dd7cddfSDavid du Colombier r = o->param;
9037dd7cddfSDavid du Colombier o1 = olr(instoffset, r, p->to.reg, p->scond);
9047dd7cddfSDavid du Colombier
9057dd7cddfSDavid du Colombier o2 = oprrr(ASLL, p->scond);
9067dd7cddfSDavid du Colombier o3 = oprrr(ASRA, p->scond);
9077dd7cddfSDavid du Colombier r = p->to.reg;
9087dd7cddfSDavid du Colombier if(p->as == AMOVB) {
9097dd7cddfSDavid du Colombier o2 |= (24<<7)|(r)|(r<<12);
9107dd7cddfSDavid du Colombier o3 |= (24<<7)|(r)|(r<<12);
9117dd7cddfSDavid du Colombier } else {
9127dd7cddfSDavid du Colombier o2 |= (16<<7)|(r)|(r<<12);
9137dd7cddfSDavid du Colombier if(p->as == AMOVHU)
9147dd7cddfSDavid du Colombier o3 = oprrr(ASRL, p->scond);
9157dd7cddfSDavid du Colombier o3 |= (16<<7)|(r)|(r<<12);
9167dd7cddfSDavid du Colombier }
9177dd7cddfSDavid du Colombier break;
9187dd7cddfSDavid du Colombier
9197dd7cddfSDavid du Colombier case 23: /* movh/movhu R,O(R) -> sb,sb */
9207dd7cddfSDavid du Colombier aclass(&p->to);
9217dd7cddfSDavid du Colombier r = p->to.reg;
9227dd7cddfSDavid du Colombier if(r == NREG)
9237dd7cddfSDavid du Colombier r = o->param;
9247dd7cddfSDavid du Colombier o1 = osr(AMOVH, p->from.reg, instoffset, r, p->scond);
9257dd7cddfSDavid du Colombier
9267dd7cddfSDavid du Colombier o2 = oprrr(ASRL, p->scond);
9277dd7cddfSDavid du Colombier o2 |= (8<<7)|(p->from.reg)|(REGTMP<<12);
9287dd7cddfSDavid du Colombier
9297dd7cddfSDavid du Colombier o3 = osr(AMOVH, REGTMP, instoffset+1, r, p->scond);
9307dd7cddfSDavid du Colombier break;
9317dd7cddfSDavid du Colombier
9327dd7cddfSDavid du Colombier case 30: /* mov/movb/movbu R,L(R) */
93359cc4ca5SDavid du Colombier o1 = omvl(p, &p->to, REGTMP);
93459cc4ca5SDavid du Colombier if(!o1)
9357dd7cddfSDavid du Colombier break;
9367dd7cddfSDavid du Colombier r = p->to.reg;
9377dd7cddfSDavid du Colombier if(r == NREG)
9387dd7cddfSDavid du Colombier r = o->param;
9397dd7cddfSDavid du Colombier o2 = osrr(p->from.reg, REGTMP,r, p->scond);
9407dd7cddfSDavid du Colombier if(p->as != AMOVW)
9417dd7cddfSDavid du Colombier o2 |= 1<<22;
9427dd7cddfSDavid du Colombier break;
9437dd7cddfSDavid du Colombier
9447dd7cddfSDavid du Colombier case 31: /* mov/movbu L(R),R -> lr[b] */
9457dd7cddfSDavid du Colombier case 32: /* movh/movb L(R),R -> lr[b] */
94659cc4ca5SDavid du Colombier o1 = omvl(p, &p->from, REGTMP);
94759cc4ca5SDavid du Colombier if(!o1)
9487dd7cddfSDavid du Colombier break;
9497dd7cddfSDavid du Colombier r = p->from.reg;
9507dd7cddfSDavid du Colombier if(r == NREG)
9517dd7cddfSDavid du Colombier r = o->param;
9527dd7cddfSDavid du Colombier o2 = olrr(REGTMP,r, p->to.reg, p->scond);
95359cc4ca5SDavid du Colombier if(p->as == AMOVBU || p->as == AMOVB)
9547dd7cddfSDavid du Colombier o2 |= 1<<22;
9557dd7cddfSDavid du Colombier if(o->type == 31)
9567dd7cddfSDavid du Colombier break;
9577dd7cddfSDavid du Colombier
9587dd7cddfSDavid du Colombier o3 = oprrr(ASLL, p->scond);
9597dd7cddfSDavid du Colombier
9607dd7cddfSDavid du Colombier if(p->as == AMOVBU || p->as == AMOVHU)
9617dd7cddfSDavid du Colombier o4 = oprrr(ASRL, p->scond);
9627dd7cddfSDavid du Colombier else
9637dd7cddfSDavid du Colombier o4 = oprrr(ASRA, p->scond);
9647dd7cddfSDavid du Colombier
9657dd7cddfSDavid du Colombier r = p->to.reg;
9667dd7cddfSDavid du Colombier o3 |= (r)|(r<<12);
9677dd7cddfSDavid du Colombier o4 |= (r)|(r<<12);
9687dd7cddfSDavid du Colombier if(p->as == AMOVB || p->as == AMOVBU) {
9697dd7cddfSDavid du Colombier o3 |= (24<<7);
9707dd7cddfSDavid du Colombier o4 |= (24<<7);
9717dd7cddfSDavid du Colombier } else {
9727dd7cddfSDavid du Colombier o3 |= (16<<7);
9737dd7cddfSDavid du Colombier o4 |= (16<<7);
9747dd7cddfSDavid du Colombier }
9757dd7cddfSDavid du Colombier break;
9767dd7cddfSDavid du Colombier
97759cc4ca5SDavid du Colombier case 33: /* movh/movhu R,L(R) -> sb, sb */
97859cc4ca5SDavid du Colombier o1 = omvl(p, &p->to, REGTMP);
97959cc4ca5SDavid du Colombier if(!o1)
9807dd7cddfSDavid du Colombier break;
9817dd7cddfSDavid du Colombier r = p->to.reg;
9827dd7cddfSDavid du Colombier if(r == NREG)
9837dd7cddfSDavid du Colombier r = o->param;
98459cc4ca5SDavid du Colombier o2 = osrr(p->from.reg, REGTMP, r, p->scond);
98559cc4ca5SDavid du Colombier o2 |= (1<<22) ;
98659cc4ca5SDavid du Colombier
98759cc4ca5SDavid du Colombier o3 = oprrr(ASRL, p->scond);
98859cc4ca5SDavid du Colombier o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12);
98959cc4ca5SDavid du Colombier o3 |= (1<<6); /* ROR 8 */
99059cc4ca5SDavid du Colombier
99159cc4ca5SDavid du Colombier o4 = oprrr(AADD, p->scond);
99259cc4ca5SDavid du Colombier o4 |= (REGTMP << 12) | (REGTMP << 16);
99359cc4ca5SDavid du Colombier o4 |= immrot(1);
99459cc4ca5SDavid du Colombier
99559cc4ca5SDavid du Colombier o5 = osrr(p->from.reg, REGTMP,r,p->scond);
99659cc4ca5SDavid du Colombier o5 |= (1<<22);
99759cc4ca5SDavid du Colombier
99859cc4ca5SDavid du Colombier o6 = oprrr(ASRL, p->scond);
99959cc4ca5SDavid du Colombier o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12);
100059cc4ca5SDavid du Colombier o6 |= (1<<6); /* ROL 8 */
100159cc4ca5SDavid du Colombier
10027dd7cddfSDavid du Colombier break;
10037dd7cddfSDavid du Colombier
10047dd7cddfSDavid du Colombier case 34: /* mov $lacon,R */
100559cc4ca5SDavid du Colombier o1 = omvl(p, &p->from, REGTMP);
100659cc4ca5SDavid du Colombier if(!o1)
10077dd7cddfSDavid du Colombier break;
10087dd7cddfSDavid du Colombier
10097dd7cddfSDavid du Colombier o2 = oprrr(AADD, p->scond);
10107dd7cddfSDavid du Colombier o2 |= REGTMP;
101180ee5cbfSDavid du Colombier r = p->from.reg;
10127dd7cddfSDavid du Colombier if(r == NREG)
10137dd7cddfSDavid du Colombier r = o->param;
10147dd7cddfSDavid du Colombier o2 |= r << 16;
10157dd7cddfSDavid du Colombier if(p->to.type != D_NONE)
10167dd7cddfSDavid du Colombier o2 |= p->to.reg << 12;
10177dd7cddfSDavid du Colombier break;
10187dd7cddfSDavid du Colombier
10197dd7cddfSDavid du Colombier case 35: /* mov PSR,R */
10207dd7cddfSDavid du Colombier o1 = (2<<23) | (0xf<<16) | (0<<0);
10217dd7cddfSDavid du Colombier o1 |= (p->scond & C_SCOND) << 28;
10227dd7cddfSDavid du Colombier o1 |= (p->from.reg & 1) << 22;
10237dd7cddfSDavid du Colombier o1 |= p->to.reg << 12;
10247dd7cddfSDavid du Colombier break;
10257dd7cddfSDavid du Colombier
10267dd7cddfSDavid du Colombier case 36: /* mov R,PSR */
10277dd7cddfSDavid du Colombier o1 = (2<<23) | (0x29f<<12) | (0<<4);
10287dd7cddfSDavid du Colombier if(p->scond & C_FBIT)
10297dd7cddfSDavid du Colombier o1 ^= 0x010 << 12;
10307dd7cddfSDavid du Colombier o1 |= (p->scond & C_SCOND) << 28;
10317dd7cddfSDavid du Colombier o1 |= (p->to.reg & 1) << 22;
10327dd7cddfSDavid du Colombier o1 |= p->from.reg << 0;
10337dd7cddfSDavid du Colombier break;
10347dd7cddfSDavid du Colombier
10357dd7cddfSDavid du Colombier case 37: /* mov $con,PSR */
10367dd7cddfSDavid du Colombier aclass(&p->from);
10377dd7cddfSDavid du Colombier o1 = (2<<23) | (0x29f<<12) | (0<<4);
10387dd7cddfSDavid du Colombier if(p->scond & C_FBIT)
10397dd7cddfSDavid du Colombier o1 ^= 0x010 << 12;
10407dd7cddfSDavid du Colombier o1 |= (p->scond & C_SCOND) << 28;
10417dd7cddfSDavid du Colombier o1 |= immrot(instoffset);
10427dd7cddfSDavid du Colombier o1 |= (p->to.reg & 1) << 22;
10437dd7cddfSDavid du Colombier o1 |= p->from.reg << 0;
10447dd7cddfSDavid du Colombier break;
10457dd7cddfSDavid du Colombier
10467dd7cddfSDavid du Colombier case 38: /* movm $con,oreg -> stm */
10477dd7cddfSDavid du Colombier o1 = (0x4 << 25);
10487dd7cddfSDavid du Colombier o1 |= p->from.offset & 0xffff;
10497dd7cddfSDavid du Colombier o1 |= p->to.reg << 16;
10507dd7cddfSDavid du Colombier aclass(&p->to);
10517dd7cddfSDavid du Colombier goto movm;
10527dd7cddfSDavid du Colombier
10537dd7cddfSDavid du Colombier case 39: /* movm oreg,$con -> ldm */
10547dd7cddfSDavid du Colombier o1 = (0x4 << 25) | (1 << 20);
10557dd7cddfSDavid du Colombier o1 |= p->to.offset & 0xffff;
10567dd7cddfSDavid du Colombier o1 |= p->from.reg << 16;
10577dd7cddfSDavid du Colombier aclass(&p->from);
10587dd7cddfSDavid du Colombier movm:
10597dd7cddfSDavid du Colombier if(instoffset != 0)
10607dd7cddfSDavid du Colombier diag("offset must be zero in MOVM");
10617dd7cddfSDavid du Colombier o1 |= (p->scond & C_SCOND) << 28;
10627dd7cddfSDavid du Colombier if(p->scond & C_PBIT)
10637dd7cddfSDavid du Colombier o1 |= 1 << 24;
10647dd7cddfSDavid du Colombier if(p->scond & C_UBIT)
10657dd7cddfSDavid du Colombier o1 |= 1 << 23;
10667dd7cddfSDavid du Colombier if(p->scond & C_SBIT)
10677dd7cddfSDavid du Colombier o1 |= 1 << 22;
10687dd7cddfSDavid du Colombier if(p->scond & C_WBIT)
10697dd7cddfSDavid du Colombier o1 |= 1 << 21;
10707dd7cddfSDavid du Colombier break;
10717dd7cddfSDavid du Colombier
10727dd7cddfSDavid du Colombier case 40: /* swp oreg,reg,reg */
10737dd7cddfSDavid du Colombier aclass(&p->from);
10747dd7cddfSDavid du Colombier if(instoffset != 0)
10757dd7cddfSDavid du Colombier diag("offset must be zero in SWP");
10767dd7cddfSDavid du Colombier o1 = (0x2<<23) | (0x9<<4);
10777dd7cddfSDavid du Colombier if(p->as != ASWPW)
10787dd7cddfSDavid du Colombier o1 |= 1 << 22;
10797dd7cddfSDavid du Colombier o1 |= p->from.reg << 16;
10807dd7cddfSDavid du Colombier o1 |= p->reg << 0;
10817dd7cddfSDavid du Colombier o1 |= p->to.reg << 12;
10827dd7cddfSDavid du Colombier o1 |= (p->scond & C_SCOND) << 28;
10837dd7cddfSDavid du Colombier break;
10847dd7cddfSDavid du Colombier
10857dd7cddfSDavid du Colombier case 41: /* rfe -> movm.s.w.u 0(r13),[r15] */
10867dd7cddfSDavid du Colombier o1 = 0xe8fd8000;
10877dd7cddfSDavid du Colombier break;
10887dd7cddfSDavid du Colombier
10897dd7cddfSDavid du Colombier case 50: /* floating point store */
10907dd7cddfSDavid du Colombier v = regoff(&p->to);
10917dd7cddfSDavid du Colombier r = p->to.reg;
10927dd7cddfSDavid du Colombier if(r == NREG)
10937dd7cddfSDavid du Colombier r = o->param;
109459cc4ca5SDavid du Colombier o1 = ofsr(p->as, p->from.reg, v, r, p->scond, p);
10957dd7cddfSDavid du Colombier break;
10967dd7cddfSDavid du Colombier
10977dd7cddfSDavid du Colombier case 51: /* floating point load */
10987dd7cddfSDavid du Colombier v = regoff(&p->from);
10997dd7cddfSDavid du Colombier r = p->from.reg;
11007dd7cddfSDavid du Colombier if(r == NREG)
11017dd7cddfSDavid du Colombier r = o->param;
110259cc4ca5SDavid du Colombier o1 = ofsr(p->as, p->to.reg, v, r, p->scond, p) | (1<<20);
11037dd7cddfSDavid du Colombier break;
11047dd7cddfSDavid du Colombier
11057dd7cddfSDavid du Colombier case 52: /* floating point store, long offset UGLY */
110659cc4ca5SDavid du Colombier o1 = omvl(p, &p->to, REGTMP);
110759cc4ca5SDavid du Colombier if(!o1)
11087dd7cddfSDavid du Colombier break;
11097dd7cddfSDavid du Colombier r = p->to.reg;
11107dd7cddfSDavid du Colombier if(r == NREG)
11117dd7cddfSDavid du Colombier r = o->param;
11127dd7cddfSDavid du Colombier o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
111359cc4ca5SDavid du Colombier o3 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p);
11147dd7cddfSDavid du Colombier break;
11157dd7cddfSDavid du Colombier
11167dd7cddfSDavid du Colombier case 53: /* floating point load, long offset UGLY */
111759cc4ca5SDavid du Colombier o1 = omvl(p, &p->from, REGTMP);
111859cc4ca5SDavid du Colombier if(!o1)
11197dd7cddfSDavid du Colombier break;
11207dd7cddfSDavid du Colombier r = p->from.reg;
11217dd7cddfSDavid du Colombier if(r == NREG)
11227dd7cddfSDavid du Colombier r = o->param;
11237dd7cddfSDavid du Colombier o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
112459cc4ca5SDavid du Colombier o3 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
11257dd7cddfSDavid du Colombier break;
11267dd7cddfSDavid du Colombier
11277dd7cddfSDavid du Colombier case 54: /* floating point arith */
11287dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
11297dd7cddfSDavid du Colombier if(p->from.type == D_FCONST) {
11307dd7cddfSDavid du Colombier rf = chipfloat(p->from.ieee);
11317dd7cddfSDavid du Colombier if(rf < 0){
11327dd7cddfSDavid du Colombier diag("invalid floating-point immediate\n%P", p);
11337dd7cddfSDavid du Colombier rf = 0;
11347dd7cddfSDavid du Colombier }
11357dd7cddfSDavid du Colombier rf |= (1<<3);
11367dd7cddfSDavid du Colombier } else
11377dd7cddfSDavid du Colombier rf = p->from.reg;
11387dd7cddfSDavid du Colombier rt = p->to.reg;
11397dd7cddfSDavid du Colombier r = p->reg;
11407dd7cddfSDavid du Colombier if(p->to.type == D_NONE)
11417dd7cddfSDavid du Colombier rt = 0; /* CMP[FD] */
11427dd7cddfSDavid du Colombier else if(o1 & (1<<15))
11437dd7cddfSDavid du Colombier r = 0; /* monadic */
11447dd7cddfSDavid du Colombier else if(r == NREG)
11457dd7cddfSDavid du Colombier r = rt;
11467dd7cddfSDavid du Colombier o1 |= rf | (r<<16) | (rt<<12);
11477dd7cddfSDavid du Colombier break;
11487dd7cddfSDavid du Colombier
11497dd7cddfSDavid du Colombier case 55: /* floating point fix and float */
11507dd7cddfSDavid du Colombier o1 = oprrr(p->as, p->scond);
11517dd7cddfSDavid du Colombier rf = p->from.reg;
11527dd7cddfSDavid du Colombier rt = p->to.reg;
11537dd7cddfSDavid du Colombier if(p->to.type == D_NONE){
11547dd7cddfSDavid du Colombier rt = 0;
11557dd7cddfSDavid du Colombier diag("to.type==D_NONE (asm/fp)");
11567dd7cddfSDavid du Colombier }
11577dd7cddfSDavid du Colombier if(p->from.type == D_REG)
11587dd7cddfSDavid du Colombier o1 |= (rf<<12) | (rt<<16);
11597dd7cddfSDavid du Colombier else
11607dd7cddfSDavid du Colombier o1 |= rf | (rt<<12);
11617dd7cddfSDavid du Colombier break;
11627dd7cddfSDavid du Colombier
1163b8b25780SDavid du Colombier /* old arm 7500 fp using coproc 1 (1<<8) */
11647dd7cddfSDavid du Colombier case 56: /* move to FP[CS]R */
11657dd7cddfSDavid du Colombier o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
11667dd7cddfSDavid du Colombier o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12);
11677dd7cddfSDavid du Colombier break;
11687dd7cddfSDavid du Colombier
11697dd7cddfSDavid du Colombier case 57: /* move from FP[CS]R */
11707dd7cddfSDavid du Colombier o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
11717dd7cddfSDavid du Colombier o1 |= ((p->from.reg+1)<<21) | (p->to.reg<<12) | (1<<20);
11727dd7cddfSDavid du Colombier break;
117359cc4ca5SDavid du Colombier case 58: /* movbu R,R */
11747dd7cddfSDavid du Colombier o1 = oprrr(AAND, p->scond);
11757dd7cddfSDavid du Colombier o1 |= immrot(0xff);
11767dd7cddfSDavid du Colombier rt = p->to.reg;
11777dd7cddfSDavid du Colombier r = p->from.reg;
11787dd7cddfSDavid du Colombier if(p->to.type == D_NONE)
11797dd7cddfSDavid du Colombier rt = 0;
11807dd7cddfSDavid du Colombier if(r == NREG)
11817dd7cddfSDavid du Colombier r = rt;
11827dd7cddfSDavid du Colombier o1 |= (r<<16) | (rt<<12);
11837dd7cddfSDavid du Colombier break;
118459cc4ca5SDavid du Colombier
118559cc4ca5SDavid du Colombier case 59: /* movw/bu R<<I(R),R -> ldr indexed */
118659cc4ca5SDavid du Colombier if(p->from.reg == NREG) {
118759cc4ca5SDavid du Colombier if(p->as != AMOVW)
118859cc4ca5SDavid du Colombier diag("byte MOV from shifter operand");
118959cc4ca5SDavid du Colombier goto mov;
119059cc4ca5SDavid du Colombier }
119159cc4ca5SDavid du Colombier if(p->from.offset&(1<<4))
119259cc4ca5SDavid du Colombier diag("bad shift in LDR");
119359cc4ca5SDavid du Colombier o1 = olrr(p->from.offset, p->from.reg, p->to.reg, p->scond);
119459cc4ca5SDavid du Colombier if(p->as == AMOVBU)
119559cc4ca5SDavid du Colombier o1 |= 1<<22;
119659cc4ca5SDavid du Colombier break;
119759cc4ca5SDavid du Colombier
119859cc4ca5SDavid du Colombier case 60: /* movb R(R),R -> ldrsb indexed */
119959cc4ca5SDavid du Colombier if(p->from.reg == NREG) {
120059cc4ca5SDavid du Colombier diag("byte MOV from shifter operand");
120159cc4ca5SDavid du Colombier goto mov;
120259cc4ca5SDavid du Colombier }
120359cc4ca5SDavid du Colombier if(p->from.offset&(~0xf))
120459cc4ca5SDavid du Colombier diag("bad shift in LDRSB");
120559cc4ca5SDavid du Colombier o1 = olhrr(p->from.offset, p->from.reg, p->to.reg, p->scond);
120659cc4ca5SDavid du Colombier o1 ^= (1<<5)|(1<<6);
120759cc4ca5SDavid du Colombier break;
120859cc4ca5SDavid du Colombier
120959cc4ca5SDavid du Colombier case 61: /* movw/b/bu R,R<<[IR](R) -> str indexed */
121059cc4ca5SDavid du Colombier if(p->to.reg == NREG)
121159cc4ca5SDavid du Colombier diag("MOV to shifter operand");
121259cc4ca5SDavid du Colombier o1 = osrr(p->from.reg, p->to.offset, p->to.reg, p->scond);
121359cc4ca5SDavid du Colombier if(p->as == AMOVB || p->as == AMOVBU)
121459cc4ca5SDavid du Colombier o1 |= 1<<22;
121559cc4ca5SDavid du Colombier break;
121659cc4ca5SDavid du Colombier
121759cc4ca5SDavid du Colombier case 62: /* case R -> movw R<<2(PC),PC */
121859cc4ca5SDavid du Colombier o1 = olrr(p->from.reg, REGPC, REGPC, p->scond);
121959cc4ca5SDavid du Colombier o1 |= 2<<7;
122059cc4ca5SDavid du Colombier break;
122159cc4ca5SDavid du Colombier
122259cc4ca5SDavid du Colombier case 63: /* bcase */
12239a747e4fSDavid du Colombier if(p->cond != P) {
122459cc4ca5SDavid du Colombier o1 = p->cond->pc;
1225375daca8SDavid du Colombier if(dlm)
1226375daca8SDavid du Colombier dynreloc(S, p->pc, 1);
12279a747e4fSDavid du Colombier }
12289a747e4fSDavid du Colombier break;
12299a747e4fSDavid du Colombier
12309a747e4fSDavid du Colombier /* reloc ops */
12319a747e4fSDavid du Colombier case 64: /* mov/movb/movbu R,addr */
12329a747e4fSDavid du Colombier o1 = omvl(p, &p->to, REGTMP);
12339a747e4fSDavid du Colombier if(!o1)
12349a747e4fSDavid du Colombier break;
12359a747e4fSDavid du Colombier o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);
12369a747e4fSDavid du Colombier break;
12379a747e4fSDavid du Colombier
12389a747e4fSDavid du Colombier case 65: /* mov/movbu addr,R */
12399a747e4fSDavid du Colombier case 66: /* movh/movhu/movb addr,R */
12409a747e4fSDavid du Colombier o1 = omvl(p, &p->from, REGTMP);
12419a747e4fSDavid du Colombier if(!o1)
12429a747e4fSDavid du Colombier break;
12439a747e4fSDavid du Colombier o2 = olr(0, REGTMP, p->to.reg, p->scond);
12449a747e4fSDavid du Colombier if(p->as == AMOVBU || p->as == AMOVB)
12459a747e4fSDavid du Colombier o2 |= 1<<22;
12469a747e4fSDavid du Colombier if(o->type == 65)
12479a747e4fSDavid du Colombier break;
12489a747e4fSDavid du Colombier
12499a747e4fSDavid du Colombier o3 = oprrr(ASLL, p->scond);
12509a747e4fSDavid du Colombier
12519a747e4fSDavid du Colombier if(p->as == AMOVBU || p->as == AMOVHU)
12529a747e4fSDavid du Colombier o4 = oprrr(ASRL, p->scond);
12539a747e4fSDavid du Colombier else
12549a747e4fSDavid du Colombier o4 = oprrr(ASRA, p->scond);
12559a747e4fSDavid du Colombier
12569a747e4fSDavid du Colombier r = p->to.reg;
12579a747e4fSDavid du Colombier o3 |= (r)|(r<<12);
12589a747e4fSDavid du Colombier o4 |= (r)|(r<<12);
12599a747e4fSDavid du Colombier if(p->as == AMOVB || p->as == AMOVBU) {
12609a747e4fSDavid du Colombier o3 |= (24<<7);
12619a747e4fSDavid du Colombier o4 |= (24<<7);
12629a747e4fSDavid du Colombier } else {
12639a747e4fSDavid du Colombier o3 |= (16<<7);
12649a747e4fSDavid du Colombier o4 |= (16<<7);
12659a747e4fSDavid du Colombier }
12669a747e4fSDavid du Colombier break;
12679a747e4fSDavid du Colombier
12689a747e4fSDavid du Colombier case 67: /* movh/movhu R,addr -> sb, sb */
12699a747e4fSDavid du Colombier o1 = omvl(p, &p->to, REGTMP);
12709a747e4fSDavid du Colombier if(!o1)
12719a747e4fSDavid du Colombier break;
12729a747e4fSDavid du Colombier o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);
12739a747e4fSDavid du Colombier
12749a747e4fSDavid du Colombier o3 = oprrr(ASRL, p->scond);
12759a747e4fSDavid du Colombier o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12);
12769a747e4fSDavid du Colombier o3 |= (1<<6); /* ROR 8 */
12779a747e4fSDavid du Colombier
12789a747e4fSDavid du Colombier o4 = oprrr(AADD, p->scond);
12799a747e4fSDavid du Colombier o4 |= (REGTMP << 12) | (REGTMP << 16);
12809a747e4fSDavid du Colombier o4 |= immrot(1);
12819a747e4fSDavid du Colombier
12829a747e4fSDavid du Colombier o5 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);
12839a747e4fSDavid du Colombier
12849a747e4fSDavid du Colombier o6 = oprrr(ASRL, p->scond);
12859a747e4fSDavid du Colombier o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12);
12869a747e4fSDavid du Colombier o6 |= (1<<6); /* ROL 8 */
12879a747e4fSDavid du Colombier break;
12889a747e4fSDavid du Colombier
12899a747e4fSDavid du Colombier case 68: /* floating point store -> ADDR */
12909a747e4fSDavid du Colombier o1 = omvl(p, &p->to, REGTMP);
12919a747e4fSDavid du Colombier if(!o1)
12929a747e4fSDavid du Colombier break;
12939a747e4fSDavid du Colombier o2 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p);
12949a747e4fSDavid du Colombier break;
12959a747e4fSDavid du Colombier
12969a747e4fSDavid du Colombier case 69: /* floating point load <- ADDR */
12979a747e4fSDavid du Colombier o1 = omvl(p, &p->from, REGTMP);
12989a747e4fSDavid du Colombier if(!o1)
12999a747e4fSDavid du Colombier break;
13009a747e4fSDavid du Colombier o2 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
130159cc4ca5SDavid du Colombier break;
130259cc4ca5SDavid du Colombier
130359cc4ca5SDavid du Colombier /* ArmV4 ops: */
130459cc4ca5SDavid du Colombier case 70: /* movh/movhu R,O(R) -> strh */
130559cc4ca5SDavid du Colombier aclass(&p->to);
130659cc4ca5SDavid du Colombier r = p->to.reg;
130759cc4ca5SDavid du Colombier if(r == NREG)
130859cc4ca5SDavid du Colombier r = o->param;
130959cc4ca5SDavid du Colombier o1 = oshr(p->from.reg, instoffset, r, p->scond);
131059cc4ca5SDavid du Colombier break;
131159cc4ca5SDavid du Colombier case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
131259cc4ca5SDavid du Colombier aclass(&p->from);
131359cc4ca5SDavid du Colombier r = p->from.reg;
131459cc4ca5SDavid du Colombier if(r == NREG)
131559cc4ca5SDavid du Colombier r = o->param;
131659cc4ca5SDavid du Colombier o1 = olhr(instoffset, r, p->to.reg, p->scond);
131759cc4ca5SDavid du Colombier if(p->as == AMOVB)
131859cc4ca5SDavid du Colombier o1 ^= (1<<5)|(1<<6);
131959cc4ca5SDavid du Colombier else if(p->as == AMOVH)
132059cc4ca5SDavid du Colombier o1 ^= (1<<6);
132159cc4ca5SDavid du Colombier break;
132259cc4ca5SDavid du Colombier case 72: /* movh/movhu R,L(R) -> strh */
132359cc4ca5SDavid du Colombier o1 = omvl(p, &p->to, REGTMP);
132459cc4ca5SDavid du Colombier if(!o1)
132559cc4ca5SDavid du Colombier break;
132659cc4ca5SDavid du Colombier r = p->to.reg;
132759cc4ca5SDavid du Colombier if(r == NREG)
132859cc4ca5SDavid du Colombier r = o->param;
132959cc4ca5SDavid du Colombier o2 = oshrr(p->from.reg, REGTMP,r, p->scond);
133059cc4ca5SDavid du Colombier break;
133159cc4ca5SDavid du Colombier case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */
133259cc4ca5SDavid du Colombier o1 = omvl(p, &p->from, REGTMP);
133359cc4ca5SDavid du Colombier if(!o1)
133459cc4ca5SDavid du Colombier break;
133559cc4ca5SDavid du Colombier r = p->from.reg;
133659cc4ca5SDavid du Colombier if(r == NREG)
133759cc4ca5SDavid du Colombier r = o->param;
133859cc4ca5SDavid du Colombier o2 = olhrr(REGTMP, r, p->to.reg, p->scond);
133959cc4ca5SDavid du Colombier if(p->as == AMOVB)
134059cc4ca5SDavid du Colombier o2 ^= (1<<5)|(1<<6);
134159cc4ca5SDavid du Colombier else if(p->as == AMOVH)
134259cc4ca5SDavid du Colombier o2 ^= (1<<6);
134359cc4ca5SDavid du Colombier break;
13449b7bf7dfSDavid du Colombier
13459b7bf7dfSDavid du Colombier /* VFP ops: */
13469b7bf7dfSDavid du Colombier case 74: /* vfp floating point arith */
13479b7bf7dfSDavid du Colombier o1 = opvfprrr(p->as, p->scond);
13489b7bf7dfSDavid du Colombier rf = p->from.reg;
13499b7bf7dfSDavid du Colombier if(p->from.type == D_FCONST) {
13509b7bf7dfSDavid du Colombier diag("invalid floating-point immediate\n%P", p);
13519b7bf7dfSDavid du Colombier rf = 0;
13529b7bf7dfSDavid du Colombier }
13539b7bf7dfSDavid du Colombier rt = p->to.reg;
13549b7bf7dfSDavid du Colombier r = p->reg;
13559b7bf7dfSDavid du Colombier if(r == NREG)
13569b7bf7dfSDavid du Colombier r = rt;
13579b7bf7dfSDavid du Colombier o1 |= rt<<12;
13589b7bf7dfSDavid du Colombier if(((o1>>20)&0xf) == 0xb)
13599b7bf7dfSDavid du Colombier o1 |= rf<<0;
13609b7bf7dfSDavid du Colombier else
13619b7bf7dfSDavid du Colombier o1 |= r<<16 | rf<<0;
13629b7bf7dfSDavid du Colombier break;
13639b7bf7dfSDavid du Colombier case 75: /* vfp floating point compare */
13649b7bf7dfSDavid du Colombier o1 = opvfprrr(p->as, p->scond);
13659b7bf7dfSDavid du Colombier rf = p->from.reg;
13669b7bf7dfSDavid du Colombier if(p->from.type == D_FCONST) {
13679b7bf7dfSDavid du Colombier if(p->from.ieee->h != 0 || p->from.ieee->l != 0)
13689b7bf7dfSDavid du Colombier diag("invalid floating-point immediate\n%P", p);
13699b7bf7dfSDavid du Colombier o1 |= 1<<16;
13709b7bf7dfSDavid du Colombier rf = 0;
13719b7bf7dfSDavid du Colombier }
13729b7bf7dfSDavid du Colombier rt = p->reg;
13739b7bf7dfSDavid du Colombier o1 |= rt<<12 | rf<<0;
13749b7bf7dfSDavid du Colombier o2 = 0x0ef1fa10; /* MRS APSR_nzcv, FPSCR */
13759b7bf7dfSDavid du Colombier o2 |= (p->scond & C_SCOND) << 28;
13769b7bf7dfSDavid du Colombier break;
13779b7bf7dfSDavid du Colombier case 76: /* vfp floating point fix and float */
13789b7bf7dfSDavid du Colombier o1 = opvfprrr(p->as, p->scond);
13799b7bf7dfSDavid du Colombier rf = p->from.reg;
13809b7bf7dfSDavid du Colombier rt = p->to.reg;
13819b7bf7dfSDavid du Colombier if(p->from.type == D_REG) {
13829b7bf7dfSDavid du Colombier o2 = o1 | rt<<12 | rt<<0;
13839b7bf7dfSDavid du Colombier o1 = 0x0e000a10; /* VMOV F,R */
13849b7bf7dfSDavid du Colombier o1 |= (p->scond & C_SCOND) << 28 | rt<<16 | rf<<12;
13859b7bf7dfSDavid du Colombier } else {
13869b7bf7dfSDavid du Colombier o1 |= FREGTMP<<12 | rf<<0;
13879b7bf7dfSDavid du Colombier o2 = 0x0e100a10; /* VMOV R,F */
13889b7bf7dfSDavid du Colombier o2 |= (p->scond & C_SCOND) << 28 | FREGTMP<<16 | rt<<12;
13899b7bf7dfSDavid du Colombier }
13909b7bf7dfSDavid du Colombier break;
13917dd7cddfSDavid du Colombier }
13927dd7cddfSDavid du Colombier
13939a747e4fSDavid du Colombier if(debug['a'] > 1)
13949a747e4fSDavid du Colombier Bprint(&bso, "%2d ", o->type);
13959a747e4fSDavid du Colombier
13967dd7cddfSDavid du Colombier v = p->pc;
13977dd7cddfSDavid du Colombier switch(o->size) {
13987dd7cddfSDavid du Colombier default:
13997dd7cddfSDavid du Colombier if(debug['a'])
14007dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
14017dd7cddfSDavid du Colombier break;
14027dd7cddfSDavid du Colombier case 4:
14037dd7cddfSDavid du Colombier if(debug['a'])
14047dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
14057dd7cddfSDavid du Colombier lputl(o1);
14067dd7cddfSDavid du Colombier break;
14077dd7cddfSDavid du Colombier case 8:
14087dd7cddfSDavid du Colombier if(debug['a'])
14097dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
14107dd7cddfSDavid du Colombier lputl(o1);
14117dd7cddfSDavid du Colombier lputl(o2);
14127dd7cddfSDavid du Colombier break;
14137dd7cddfSDavid du Colombier case 12:
14147dd7cddfSDavid du Colombier if(debug['a'])
14157dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
14167dd7cddfSDavid du Colombier lputl(o1);
14177dd7cddfSDavid du Colombier lputl(o2);
14187dd7cddfSDavid du Colombier lputl(o3);
14197dd7cddfSDavid du Colombier break;
14207dd7cddfSDavid du Colombier case 16:
14217dd7cddfSDavid du Colombier if(debug['a'])
14227dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
14237dd7cddfSDavid du Colombier v, o1, o2, o3, o4, p);
14247dd7cddfSDavid du Colombier lputl(o1);
14257dd7cddfSDavid du Colombier lputl(o2);
14267dd7cddfSDavid du Colombier lputl(o3);
14277dd7cddfSDavid du Colombier lputl(o4);
14287dd7cddfSDavid du Colombier break;
14297dd7cddfSDavid du Colombier case 20:
14307dd7cddfSDavid du Colombier if(debug['a'])
14317dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
14327dd7cddfSDavid du Colombier v, o1, o2, o3, o4, o5, p);
14337dd7cddfSDavid du Colombier lputl(o1);
14347dd7cddfSDavid du Colombier lputl(o2);
14357dd7cddfSDavid du Colombier lputl(o3);
14367dd7cddfSDavid du Colombier lputl(o4);
14377dd7cddfSDavid du Colombier lputl(o5);
14387dd7cddfSDavid du Colombier break;
143959cc4ca5SDavid du Colombier case 24:
144059cc4ca5SDavid du Colombier if(debug['a'])
144159cc4ca5SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
144259cc4ca5SDavid du Colombier v, o1, o2, o3, o4, o5, o6, p);
144359cc4ca5SDavid du Colombier lputl(o1);
144459cc4ca5SDavid du Colombier lputl(o2);
144559cc4ca5SDavid du Colombier lputl(o3);
144659cc4ca5SDavid du Colombier lputl(o4);
144759cc4ca5SDavid du Colombier lputl(o5);
144859cc4ca5SDavid du Colombier lputl(o6);
144959cc4ca5SDavid du Colombier break;
14507dd7cddfSDavid du Colombier }
14517dd7cddfSDavid du Colombier }
14527dd7cddfSDavid du Colombier
14537dd7cddfSDavid du Colombier long
oprrr(int a,int sc)14547dd7cddfSDavid du Colombier oprrr(int a, int sc)
14557dd7cddfSDavid du Colombier {
14567dd7cddfSDavid du Colombier long o;
14577dd7cddfSDavid du Colombier
14587dd7cddfSDavid du Colombier o = (sc & C_SCOND) << 28;
14597dd7cddfSDavid du Colombier if(sc & C_SBIT)
14607dd7cddfSDavid du Colombier o |= 1 << 20;
14617dd7cddfSDavid du Colombier if(sc & (C_PBIT|C_WBIT))
14627dd7cddfSDavid du Colombier diag(".P/.W on dp instruction");
14637dd7cddfSDavid du Colombier switch(a) {
14647dd7cddfSDavid du Colombier case AMULU:
14657dd7cddfSDavid du Colombier case AMUL: return o | (0x0<<21) | (0x9<<4);
146659cc4ca5SDavid du Colombier case AMULA: return o | (0x1<<21) | (0x9<<4);
146759cc4ca5SDavid du Colombier case AMULLU: return o | (0x4<<21) | (0x9<<4);
146859cc4ca5SDavid du Colombier case AMULL: return o | (0x6<<21) | (0x9<<4);
146959cc4ca5SDavid du Colombier case AMULALU: return o | (0x5<<21) | (0x9<<4);
147059cc4ca5SDavid du Colombier case AMULAL: return o | (0x7<<21) | (0x9<<4);
14717dd7cddfSDavid du Colombier case AAND: return o | (0x0<<21);
14727dd7cddfSDavid du Colombier case AEOR: return o | (0x1<<21);
14737dd7cddfSDavid du Colombier case ASUB: return o | (0x2<<21);
14747dd7cddfSDavid du Colombier case ARSB: return o | (0x3<<21);
14757dd7cddfSDavid du Colombier case AADD: return o | (0x4<<21);
14767dd7cddfSDavid du Colombier case AADC: return o | (0x5<<21);
14777dd7cddfSDavid du Colombier case ASBC: return o | (0x6<<21);
14787dd7cddfSDavid du Colombier case ARSC: return o | (0x7<<21);
14797dd7cddfSDavid du Colombier case ATST: return o | (0x8<<21) | (1<<20);
14807dd7cddfSDavid du Colombier case ATEQ: return o | (0x9<<21) | (1<<20);
14817dd7cddfSDavid du Colombier case ACMP: return o | (0xa<<21) | (1<<20);
148259cc4ca5SDavid du Colombier case ACMN: return o | (0xb<<21) | (1<<20);
14837dd7cddfSDavid du Colombier case AORR: return o | (0xc<<21);
14847dd7cddfSDavid du Colombier case AMOVW: return o | (0xd<<21);
14857dd7cddfSDavid du Colombier case ABIC: return o | (0xe<<21);
14867dd7cddfSDavid du Colombier case AMVN: return o | (0xf<<21);
14877dd7cddfSDavid du Colombier case ASLL: return o | (0xd<<21) | (0<<5);
14887dd7cddfSDavid du Colombier case ASRL: return o | (0xd<<21) | (1<<5);
14897dd7cddfSDavid du Colombier case ASRA: return o | (0xd<<21) | (2<<5);
14907dd7cddfSDavid du Colombier case ASWI: return o | (0xf<<24);
14917dd7cddfSDavid du Colombier
1492b8b25780SDavid du Colombier /* old arm 7500 fp using coproc 1 (1<<8) */
14937dd7cddfSDavid du Colombier case AADDD: return o | (0xe<<24) | (0x0<<20) | (1<<8) | (1<<7);
14947dd7cddfSDavid du Colombier case AADDF: return o | (0xe<<24) | (0x0<<20) | (1<<8);
14957dd7cddfSDavid du Colombier case AMULD: return o | (0xe<<24) | (0x1<<20) | (1<<8) | (1<<7);
14967dd7cddfSDavid du Colombier case AMULF: return o | (0xe<<24) | (0x1<<20) | (1<<8);
14977dd7cddfSDavid du Colombier case ASUBD: return o | (0xe<<24) | (0x2<<20) | (1<<8) | (1<<7);
14987dd7cddfSDavid du Colombier case ASUBF: return o | (0xe<<24) | (0x2<<20) | (1<<8);
14997dd7cddfSDavid du Colombier case ADIVD: return o | (0xe<<24) | (0x4<<20) | (1<<8) | (1<<7);
15007dd7cddfSDavid du Colombier case ADIVF: return o | (0xe<<24) | (0x4<<20) | (1<<8);
15017dd7cddfSDavid du Colombier case ACMPD:
15027dd7cddfSDavid du Colombier case ACMPF: return o | (0xe<<24) | (0x9<<20) | (0xF<<12) | (1<<8) | (1<<4); /* arguably, ACMPF should expand to RNDF, CMPD */
15037dd7cddfSDavid du Colombier
15047dd7cddfSDavid du Colombier case AMOVF:
15057dd7cddfSDavid du Colombier case AMOVDF: return o | (0xe<<24) | (0x0<<20) | (1<<15) | (1<<8);
15067dd7cddfSDavid du Colombier case AMOVD:
15077dd7cddfSDavid du Colombier case AMOVFD: return o | (0xe<<24) | (0x0<<20) | (1<<15) | (1<<8) | (1<<7);
15087dd7cddfSDavid du Colombier
15097dd7cddfSDavid du Colombier case AMOVWF: return o | (0xe<<24) | (0<<20) | (1<<8) | (1<<4);
15107dd7cddfSDavid du Colombier case AMOVWD: return o | (0xe<<24) | (0<<20) | (1<<8) | (1<<4) | (1<<7);
15117dd7cddfSDavid du Colombier case AMOVFW: return o | (0xe<<24) | (1<<20) | (1<<8) | (1<<4);
15127dd7cddfSDavid du Colombier case AMOVDW: return o | (0xe<<24) | (1<<20) | (1<<8) | (1<<4) | (1<<7);
15137dd7cddfSDavid du Colombier }
15147dd7cddfSDavid du Colombier diag("bad rrr %d", a);
15157dd7cddfSDavid du Colombier prasm(curp);
15167dd7cddfSDavid du Colombier return 0;
15177dd7cddfSDavid du Colombier }
15187dd7cddfSDavid du Colombier
15197dd7cddfSDavid du Colombier long
opvfprrr(int a,int sc)15209b7bf7dfSDavid du Colombier opvfprrr(int a, int sc)
15219b7bf7dfSDavid du Colombier {
15229b7bf7dfSDavid du Colombier long o;
15239b7bf7dfSDavid du Colombier
15249b7bf7dfSDavid du Colombier o = (sc & C_SCOND) << 28;
15259b7bf7dfSDavid du Colombier if(sc & (C_SBIT|C_PBIT|C_WBIT))
15269b7bf7dfSDavid du Colombier diag(".S/.P/.W on vfp instruction");
15279b7bf7dfSDavid du Colombier o |= 0xe<<24;
15289b7bf7dfSDavid du Colombier switch(a) {
15299b7bf7dfSDavid du Colombier case AMOVWD: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x8<<16 | 1<<7;
15309b7bf7dfSDavid du Colombier case AMOVWF: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x8<<16 | 1<<7;
15319b7bf7dfSDavid du Colombier case AMOVDW: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0xD<<16 | 1<<7;
15329b7bf7dfSDavid du Colombier case AMOVFW: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0xD<<16 | 1<<7;
15339b7bf7dfSDavid du Colombier case AMOVFD: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x7<<16 | 1<<7;
15349b7bf7dfSDavid du Colombier case AMOVDF: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x7<<16 | 1<<7;
15359b7bf7dfSDavid du Colombier case AMOVF: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x0<<16 | 0<<7;
15369b7bf7dfSDavid du Colombier case AMOVD: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x0<<16 | 0<<7;
15379b7bf7dfSDavid du Colombier case ACMPF: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x4<<16 | 0<<7;
15389b7bf7dfSDavid du Colombier case ACMPD: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x4<<16 | 0<<7;
15399b7bf7dfSDavid du Colombier case AADDF: return o | 0xa<<8 | 0x3<<20;
15409b7bf7dfSDavid du Colombier case AADDD: return o | 0xb<<8 | 0x3<<20;
15419b7bf7dfSDavid du Colombier case ASUBF: return o | 0xa<<8 | 0x3<<20 | 1<<6;
15429b7bf7dfSDavid du Colombier case ASUBD: return o | 0xb<<8 | 0x3<<20 | 1<<6;
15439b7bf7dfSDavid du Colombier case AMULF: return o | 0xa<<8 | 0x2<<20;
15449b7bf7dfSDavid du Colombier case AMULD: return o | 0xb<<8 | 0x2<<20;
15459b7bf7dfSDavid du Colombier case ADIVF: return o | 0xa<<8 | 0x8<<20;
15469b7bf7dfSDavid du Colombier case ADIVD: return o | 0xb<<8 | 0x8<<20;
15479b7bf7dfSDavid du Colombier }
15489b7bf7dfSDavid du Colombier diag("bad vfp rrr %d", a);
15499b7bf7dfSDavid du Colombier prasm(curp);
15509b7bf7dfSDavid du Colombier return 0;
15519b7bf7dfSDavid du Colombier }
15529b7bf7dfSDavid du Colombier
15539b7bf7dfSDavid du Colombier long
opbra(int a,int sc)15547dd7cddfSDavid du Colombier opbra(int a, int sc)
15557dd7cddfSDavid du Colombier {
15567dd7cddfSDavid du Colombier
15577dd7cddfSDavid du Colombier if(sc & (C_SBIT|C_PBIT|C_WBIT))
15587dd7cddfSDavid du Colombier diag(".S/.P/.W on bra instruction");
15597dd7cddfSDavid du Colombier sc &= C_SCOND;
15607dd7cddfSDavid du Colombier if(a == ABL)
15617dd7cddfSDavid du Colombier return (sc<<28)|(0x5<<25)|(0x1<<24);
15627dd7cddfSDavid du Colombier if(sc != 0xe)
15637dd7cddfSDavid du Colombier diag(".COND on bcond instruction");
15647dd7cddfSDavid du Colombier switch(a) {
15657dd7cddfSDavid du Colombier case ABEQ: return (0x0<<28)|(0x5<<25);
15667dd7cddfSDavid du Colombier case ABNE: return (0x1<<28)|(0x5<<25);
15677dd7cddfSDavid du Colombier case ABCS: return (0x2<<28)|(0x5<<25);
15687dd7cddfSDavid du Colombier case ABHS: return (0x2<<28)|(0x5<<25);
15697dd7cddfSDavid du Colombier case ABCC: return (0x3<<28)|(0x5<<25);
15707dd7cddfSDavid du Colombier case ABLO: return (0x3<<28)|(0x5<<25);
15717dd7cddfSDavid du Colombier case ABMI: return (0x4<<28)|(0x5<<25);
15727dd7cddfSDavid du Colombier case ABPL: return (0x5<<28)|(0x5<<25);
15737dd7cddfSDavid du Colombier case ABVS: return (0x6<<28)|(0x5<<25);
15747dd7cddfSDavid du Colombier case ABVC: return (0x7<<28)|(0x5<<25);
15757dd7cddfSDavid du Colombier case ABHI: return (0x8<<28)|(0x5<<25);
15767dd7cddfSDavid du Colombier case ABLS: return (0x9<<28)|(0x5<<25);
15777dd7cddfSDavid du Colombier case ABGE: return (0xa<<28)|(0x5<<25);
15787dd7cddfSDavid du Colombier case ABLT: return (0xb<<28)|(0x5<<25);
15797dd7cddfSDavid du Colombier case ABGT: return (0xc<<28)|(0x5<<25);
15807dd7cddfSDavid du Colombier case ABLE: return (0xd<<28)|(0x5<<25);
15817dd7cddfSDavid du Colombier case AB: return (0xe<<28)|(0x5<<25);
15827dd7cddfSDavid du Colombier }
15837dd7cddfSDavid du Colombier diag("bad bra %A", a);
15847dd7cddfSDavid du Colombier prasm(curp);
15857dd7cddfSDavid du Colombier return 0;
15867dd7cddfSDavid du Colombier }
15877dd7cddfSDavid du Colombier
15887dd7cddfSDavid du Colombier long
olr(long v,int b,int r,int sc)15897dd7cddfSDavid du Colombier olr(long v, int b, int r, int sc)
15907dd7cddfSDavid du Colombier {
15917dd7cddfSDavid du Colombier long o;
15927dd7cddfSDavid du Colombier
15937dd7cddfSDavid du Colombier if(sc & C_SBIT)
15947dd7cddfSDavid du Colombier diag(".S on LDR/STR instruction");
15957dd7cddfSDavid du Colombier o = (sc & C_SCOND) << 28;
15967dd7cddfSDavid du Colombier if(!(sc & C_PBIT))
15977dd7cddfSDavid du Colombier o |= 1 << 24;
159859cc4ca5SDavid du Colombier if(!(sc & C_UBIT))
159959cc4ca5SDavid du Colombier o |= 1 << 23;
16007dd7cddfSDavid du Colombier if(sc & C_WBIT)
16017dd7cddfSDavid du Colombier o |= 1 << 21;
160259cc4ca5SDavid du Colombier o |= (0x1<<26) | (1<<20);
16037dd7cddfSDavid du Colombier if(v < 0) {
16047dd7cddfSDavid du Colombier v = -v;
16057dd7cddfSDavid du Colombier o ^= 1 << 23;
16067dd7cddfSDavid du Colombier }
16077dd7cddfSDavid du Colombier if(v >= (1<<12))
1608406758d9SDavid du Colombier diag("literal span too large: %ld (R%d)\n%P", v, b, PP);
16097dd7cddfSDavid du Colombier o |= v;
16107dd7cddfSDavid du Colombier o |= b << 16;
16117dd7cddfSDavid du Colombier o |= r << 12;
16127dd7cddfSDavid du Colombier return o;
16137dd7cddfSDavid du Colombier }
16147dd7cddfSDavid du Colombier
16157dd7cddfSDavid du Colombier long
olhr(long v,int b,int r,int sc)161659cc4ca5SDavid du Colombier olhr(long v, int b, int r, int sc)
161759cc4ca5SDavid du Colombier {
161859cc4ca5SDavid du Colombier long o;
161959cc4ca5SDavid du Colombier
162059cc4ca5SDavid du Colombier if(sc & C_SBIT)
162159cc4ca5SDavid du Colombier diag(".S on LDRH/STRH instruction");
162259cc4ca5SDavid du Colombier o = (sc & C_SCOND) << 28;
162359cc4ca5SDavid du Colombier if(!(sc & C_PBIT))
162459cc4ca5SDavid du Colombier o |= 1 << 24;
162559cc4ca5SDavid du Colombier if(sc & C_WBIT)
162659cc4ca5SDavid du Colombier o |= 1 << 21;
162759cc4ca5SDavid du Colombier o |= (1<<23) | (1<<20)|(0xb<<4);
162859cc4ca5SDavid du Colombier if(v < 0) {
162959cc4ca5SDavid du Colombier v = -v;
163059cc4ca5SDavid du Colombier o ^= 1 << 23;
163159cc4ca5SDavid du Colombier }
163259cc4ca5SDavid du Colombier if(v >= (1<<8))
1633406758d9SDavid du Colombier diag("literal span too large: %ld (R%d)\n%P", v, b, PP);
163459cc4ca5SDavid du Colombier o |= (v&0xf)|((v>>4)<<8)|(1<<22);
163559cc4ca5SDavid du Colombier o |= b << 16;
163659cc4ca5SDavid du Colombier o |= r << 12;
163759cc4ca5SDavid du Colombier return o;
163859cc4ca5SDavid du Colombier }
163959cc4ca5SDavid du Colombier
164059cc4ca5SDavid du Colombier long
osr(int a,int r,long v,int b,int sc)16417dd7cddfSDavid du Colombier osr(int a, int r, long v, int b, int sc)
16427dd7cddfSDavid du Colombier {
16437dd7cddfSDavid du Colombier long o;
16447dd7cddfSDavid du Colombier
16457dd7cddfSDavid du Colombier o = olr(v, b, r, sc) ^ (1<<20);
16467dd7cddfSDavid du Colombier if(a != AMOVW)
16477dd7cddfSDavid du Colombier o |= 1<<22;
16487dd7cddfSDavid du Colombier return o;
16497dd7cddfSDavid du Colombier }
16507dd7cddfSDavid du Colombier
16517dd7cddfSDavid du Colombier long
oshr(int r,long v,int b,int sc)165259cc4ca5SDavid du Colombier oshr(int r, long v, int b, int sc)
165359cc4ca5SDavid du Colombier {
165459cc4ca5SDavid du Colombier long o;
165559cc4ca5SDavid du Colombier
165659cc4ca5SDavid du Colombier o = olhr(v, b, r, sc) ^ (1<<20);
165759cc4ca5SDavid du Colombier return o;
165859cc4ca5SDavid du Colombier }
165959cc4ca5SDavid du Colombier
166059cc4ca5SDavid du Colombier
166159cc4ca5SDavid du Colombier long
osrr(int r,int i,int b,int sc)16627dd7cddfSDavid du Colombier osrr(int r, int i, int b, int sc)
16637dd7cddfSDavid du Colombier {
16647dd7cddfSDavid du Colombier
16657dd7cddfSDavid du Colombier return olr(i, b, r, sc) ^ ((1<<25) | (1<<20));
16667dd7cddfSDavid du Colombier }
16677dd7cddfSDavid du Colombier
16687dd7cddfSDavid du Colombier long
oshrr(int r,int i,int b,int sc)16697dd7cddfSDavid du Colombier oshrr(int r, int i, int b, int sc)
16707dd7cddfSDavid du Colombier {
167159cc4ca5SDavid du Colombier return olhr(i, b, r, sc) ^ ((1<<22) | (1<<20));
16727dd7cddfSDavid du Colombier }
16737dd7cddfSDavid du Colombier
16747dd7cddfSDavid du Colombier long
olrr(int i,int b,int r,int sc)16757dd7cddfSDavid du Colombier olrr(int i, int b, int r, int sc)
16767dd7cddfSDavid du Colombier {
16777dd7cddfSDavid du Colombier
16787dd7cddfSDavid du Colombier return olr(i, b, r, sc) ^ (1<<25);
16797dd7cddfSDavid du Colombier }
16807dd7cddfSDavid du Colombier
16817dd7cddfSDavid du Colombier long
olhrr(int i,int b,int r,int sc)168259cc4ca5SDavid du Colombier olhrr(int i, int b, int r, int sc)
168359cc4ca5SDavid du Colombier {
168459cc4ca5SDavid du Colombier return olhr(i, b, r, sc) ^ (1<<22);
168559cc4ca5SDavid du Colombier }
168659cc4ca5SDavid du Colombier
168759cc4ca5SDavid du Colombier long
ovfpmem(int a,int r,long v,int b,int sc,Prog * p)16889b7bf7dfSDavid du Colombier ovfpmem(int a, int r, long v, int b, int sc, Prog *p)
16899b7bf7dfSDavid du Colombier {
16909b7bf7dfSDavid du Colombier long o;
16919b7bf7dfSDavid du Colombier
16929b7bf7dfSDavid du Colombier if(sc & (C_SBIT|C_PBIT|C_WBIT))
16939b7bf7dfSDavid du Colombier diag(".S/.P/.W on VLDR/VSTR instruction");
16949b7bf7dfSDavid du Colombier o = (sc & C_SCOND) << 28;
16959b7bf7dfSDavid du Colombier o |= 0xd<<24 | (1<<23);
16969b7bf7dfSDavid du Colombier if(v < 0) {
16979b7bf7dfSDavid du Colombier v = -v;
16989b7bf7dfSDavid du Colombier o ^= 1 << 23;
16999b7bf7dfSDavid du Colombier }
17009b7bf7dfSDavid du Colombier if(v & 3)
17019b7bf7dfSDavid du Colombier diag("odd offset for floating point op: %ld\n%P", v, p);
17029b7bf7dfSDavid du Colombier else if(v >= (1<<10))
17039b7bf7dfSDavid du Colombier diag("literal span too large: %ld\n%P", v, p);
17049b7bf7dfSDavid du Colombier o |= (v>>2) & 0xFF;
17059b7bf7dfSDavid du Colombier o |= b << 16;
17069b7bf7dfSDavid du Colombier o |= r << 12;
17079b7bf7dfSDavid du Colombier switch(a) {
17089b7bf7dfSDavid du Colombier default:
17099b7bf7dfSDavid du Colombier diag("bad fst %A", a);
17109b7bf7dfSDavid du Colombier case AMOVD:
17119b7bf7dfSDavid du Colombier o |= 0xb<<8;
17129b7bf7dfSDavid du Colombier break;
17139b7bf7dfSDavid du Colombier case AMOVF:
17149b7bf7dfSDavid du Colombier o |= 0xa<<8;
17159b7bf7dfSDavid du Colombier break;
17169b7bf7dfSDavid du Colombier }
17179b7bf7dfSDavid du Colombier return o;
17189b7bf7dfSDavid du Colombier }
17199b7bf7dfSDavid du Colombier
17209b7bf7dfSDavid du Colombier long
ofsr(int a,int r,long v,int b,int sc,Prog * p)172159cc4ca5SDavid du Colombier ofsr(int a, int r, long v, int b, int sc, Prog *p)
17227dd7cddfSDavid du Colombier {
17237dd7cddfSDavid du Colombier long o;
17247dd7cddfSDavid du Colombier
17259b7bf7dfSDavid du Colombier if(vfp)
17269b7bf7dfSDavid du Colombier return ovfpmem(a, r, v, b, sc, p);
17277dd7cddfSDavid du Colombier if(sc & C_SBIT)
17287dd7cddfSDavid du Colombier diag(".S on FLDR/FSTR instruction");
17297dd7cddfSDavid du Colombier o = (sc & C_SCOND) << 28;
17307dd7cddfSDavid du Colombier if(!(sc & C_PBIT))
17317dd7cddfSDavid du Colombier o |= 1 << 24;
17327dd7cddfSDavid du Colombier if(sc & C_WBIT)
17337dd7cddfSDavid du Colombier o |= 1 << 21;
17347dd7cddfSDavid du Colombier o |= (6<<25) | (1<<24) | (1<<23);
17357dd7cddfSDavid du Colombier if(v < 0) {
17367dd7cddfSDavid du Colombier v = -v;
17377dd7cddfSDavid du Colombier o ^= 1 << 23;
17387dd7cddfSDavid du Colombier }
17397dd7cddfSDavid du Colombier if(v & 3)
1740406758d9SDavid du Colombier diag("odd offset for floating point op: %ld\n%P", v, p);
17417dd7cddfSDavid du Colombier else if(v >= (1<<10))
1742406758d9SDavid du Colombier diag("literal span too large: %ld\n%P", v, p);
17437dd7cddfSDavid du Colombier o |= (v>>2) & 0xFF;
17447dd7cddfSDavid du Colombier o |= b << 16;
17457dd7cddfSDavid du Colombier o |= r << 12;
17467dd7cddfSDavid du Colombier o |= 1 << 8;
17477dd7cddfSDavid du Colombier
17487dd7cddfSDavid du Colombier switch(a) {
17497dd7cddfSDavid du Colombier default:
17507dd7cddfSDavid du Colombier diag("bad fst %A", a);
17517dd7cddfSDavid du Colombier case AMOVD:
17527dd7cddfSDavid du Colombier o |= 1<<15;
17537dd7cddfSDavid du Colombier case AMOVF:
17547dd7cddfSDavid du Colombier break;
17557dd7cddfSDavid du Colombier }
17567dd7cddfSDavid du Colombier return o;
17577dd7cddfSDavid du Colombier }
17587dd7cddfSDavid du Colombier
175959cc4ca5SDavid du Colombier long
omvl(Prog * p,Adr * a,int dr)176059cc4ca5SDavid du Colombier omvl(Prog *p, Adr *a, int dr)
176159cc4ca5SDavid du Colombier {
176259cc4ca5SDavid du Colombier long v, o1;
176359cc4ca5SDavid du Colombier if(!p->cond) {
176459cc4ca5SDavid du Colombier aclass(a);
176559cc4ca5SDavid du Colombier v = immrot(~instoffset);
176659cc4ca5SDavid du Colombier if(v == 0) {
176759cc4ca5SDavid du Colombier diag("missing literal");
176859cc4ca5SDavid du Colombier prasm(p);
176959cc4ca5SDavid du Colombier return 0;
177059cc4ca5SDavid du Colombier }
177159cc4ca5SDavid du Colombier o1 = oprrr(AMVN, p->scond&C_SCOND);
177259cc4ca5SDavid du Colombier o1 |= v;
177359cc4ca5SDavid du Colombier o1 |= dr << 12;
177459cc4ca5SDavid du Colombier } else {
177559cc4ca5SDavid du Colombier v = p->cond->pc - p->pc - 8;
177659cc4ca5SDavid du Colombier o1 = olr(v, REGPC, dr, p->scond&C_SCOND);
177759cc4ca5SDavid du Colombier }
177859cc4ca5SDavid du Colombier return o1;
177959cc4ca5SDavid du Colombier }
178059cc4ca5SDavid du Colombier
17817dd7cddfSDavid du Colombier static Ieee chipfloats[] = {
17827dd7cddfSDavid du Colombier {0x00000000, 0x00000000}, /* 0 */
17837dd7cddfSDavid du Colombier {0x00000000, 0x3ff00000}, /* 1 */
17847dd7cddfSDavid du Colombier {0x00000000, 0x40000000}, /* 2 */
17857dd7cddfSDavid du Colombier {0x00000000, 0x40080000}, /* 3 */
17867dd7cddfSDavid du Colombier {0x00000000, 0x40100000}, /* 4 */
17877dd7cddfSDavid du Colombier {0x00000000, 0x40140000}, /* 5 */
17887dd7cddfSDavid du Colombier {0x00000000, 0x3fe00000}, /* .5 */
17897dd7cddfSDavid du Colombier {0x00000000, 0x40240000}, /* 10 */
17907dd7cddfSDavid du Colombier };
17917dd7cddfSDavid du Colombier
17927dd7cddfSDavid du Colombier int
chipfloat(Ieee * e)17937dd7cddfSDavid du Colombier chipfloat(Ieee *e)
17947dd7cddfSDavid du Colombier {
17957dd7cddfSDavid du Colombier Ieee *p;
17967dd7cddfSDavid du Colombier int n;
17977dd7cddfSDavid du Colombier
17989b7bf7dfSDavid du Colombier if(vfp)
17999b7bf7dfSDavid du Colombier return -1;
18007dd7cddfSDavid du Colombier for(n = sizeof(chipfloats)/sizeof(chipfloats[0]); --n >= 0;){
18017dd7cddfSDavid du Colombier p = &chipfloats[n];
18027dd7cddfSDavid du Colombier if(p->l == e->l && p->h == e->h)
18037dd7cddfSDavid du Colombier return n;
18047dd7cddfSDavid du Colombier }
18057dd7cddfSDavid du Colombier return -1;
18067dd7cddfSDavid du Colombier }
1807