Commit a0084b34 authored by Shenghou Ma's avatar Shenghou Ma

cmd/5a, cmd/5l: add MULW{T,B} and MULAW{T,B} support for ARM

        Supported in ARMv5TE and above.
        Also corrected MULA disassembly listing.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6265045
parent f51390b2
...@@ -286,18 +286,19 @@ inst: ...@@ -286,18 +286,19 @@ inst:
outcode(AWORD, Always, &nullgen, NREG, &g); outcode(AWORD, Always, &nullgen, NREG, &g);
} }
/* /*
* MULL hi,lo,r1,r2 * MULL r1,r2,(hi,lo)
*/ */
| LTYPEM cond reg ',' reg ',' regreg | LTYPEM cond reg ',' reg ',' regreg
{ {
outcode($1, $2, &$3, $5.reg, &$7); outcode($1, $2, &$3, $5.reg, &$7);
} }
/* /*
* MULA hi,lo,r1,r2 * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
* MULAW{T,B} r1,r2,r3,r4
*/ */
| LTYPEN cond reg ',' reg ',' reg ',' spreg | LTYPEN cond reg ',' reg ',' reg ',' spreg
{ {
$7.type = D_REGREG; $7.type = D_REGREG2;
$7.offset = $9; $7.offset = $9;
outcode($1, $2, &$3, $5.reg, &$7); outcode($1, $2, &$3, $5.reg, &$7);
} }
......
...@@ -408,6 +408,11 @@ struct ...@@ -408,6 +408,11 @@ struct
"UNDEF", LTYPEE, AUNDEF, "UNDEF", LTYPEE, AUNDEF,
"CLZ", LTYPE2, ACLZ, "CLZ", LTYPE2, ACLZ,
"MULWT", LTYPE1, AMULWT,
"MULWB", LTYPE1, AMULWB,
"MULAWT", LTYPEN, AMULAWT,
"MULAWB", LTYPEN, AMULAWB,
0 0
}; };
...@@ -511,6 +516,7 @@ zaddr(Gen *a, int s) ...@@ -511,6 +516,7 @@ zaddr(Gen *a, int s)
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
Bputc(&obuf, a->offset); Bputc(&obuf, a->offset);
break; break;
......
This diff is collapsed.
...@@ -176,7 +176,7 @@ cgen64(Node *n, Node *res) ...@@ -176,7 +176,7 @@ cgen64(Node *n, Node *res)
p1->from.type = D_REG; p1->from.type = D_REG;
p1->from.reg = bl.val.u.reg; p1->from.reg = bl.val.u.reg;
p1->reg = ch.val.u.reg; p1->reg = ch.val.u.reg;
p1->to.type = D_REGREG; p1->to.type = D_REGREG2;
p1->to.reg = ah.val.u.reg; p1->to.reg = ah.val.u.reg;
p1->to.offset = ah.val.u.reg; p1->to.offset = ah.val.u.reg;
//print("%P\n", p1); //print("%P\n", p1);
...@@ -186,7 +186,7 @@ cgen64(Node *n, Node *res) ...@@ -186,7 +186,7 @@ cgen64(Node *n, Node *res)
p1->from.type = D_REG; p1->from.type = D_REG;
p1->from.reg = bh.val.u.reg; p1->from.reg = bh.val.u.reg;
p1->reg = cl.val.u.reg; p1->reg = cl.val.u.reg;
p1->to.type = D_REGREG; p1->to.type = D_REGREG2;
p1->to.reg = ah.val.u.reg; p1->to.reg = ah.val.u.reg;
p1->to.offset = ah.val.u.reg; p1->to.offset = ah.val.u.reg;
//print("%P\n", p1); //print("%P\n", p1);
......
...@@ -147,6 +147,7 @@ zaddr(Biobuf *b, Addr *a, int s) ...@@ -147,6 +147,7 @@ zaddr(Biobuf *b, Addr *a, int s)
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
Bputc(b, a->offset); Bputc(b, a->offset);
break; break;
......
...@@ -153,6 +153,12 @@ Dconv(Fmt *fp) ...@@ -153,6 +153,12 @@ Dconv(Fmt *fp)
sprint(str, "%M(R%d)(REG)", a, a->reg); sprint(str, "%M(R%d)(REG)", a, a->reg);
break; break;
case D_REGREG2:
sprint(str, "R%d,R%d", a->reg, (int)a->offset);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%M(R%d)(REG)", a, a->reg);
break;
case D_FREG: case D_FREG:
sprint(str, "F%d", a->reg); sprint(str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != S) if(a->name != D_NONE || a->sym != S)
......
...@@ -1213,7 +1213,7 @@ copyau(Adr *a, Adr *v) ...@@ -1213,7 +1213,7 @@ copyau(Adr *a, Adr *v)
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
} else } else
if(a->type == D_REGREG) { if(a->type == D_REGREG || a->type == D_REGREG2) {
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
if(a->offset == v->reg) if(a->offset == v->reg)
...@@ -1276,7 +1276,7 @@ copysub(Adr *a, Adr *v, Adr *s, int f) ...@@ -1276,7 +1276,7 @@ copysub(Adr *a, Adr *v, Adr *s, int f)
if((a->offset&(1<<4)) && (a->offset>>8) == v->reg) if((a->offset&(1<<4)) && (a->offset>>8) == v->reg)
a->offset = (a->offset&~(0xf<<8))|(s->reg<<8); a->offset = (a->offset&~(0xf<<8))|(s->reg<<8);
} else } else
if(a->type == D_REGREG) { if(a->type == D_REGREG || a->type == D_REGREG2) {
if(a->offset == v->reg) if(a->offset == v->reg)
a->offset = s->reg; a->offset = s->reg;
if(a->reg == v->reg) if(a->reg == v->reg)
......
...@@ -874,6 +874,7 @@ mkvar(Reg *r, Adr *a) ...@@ -874,6 +874,7 @@ mkvar(Reg *r, Adr *a)
goto onereg; goto onereg;
case D_REGREG: case D_REGREG:
case D_REGREG2:
bit = zbits; bit = zbits;
if(a->offset != NREG) if(a->offset != NREG)
bit.b[0] |= RtoB(a->offset); bit.b[0] |= RtoB(a->offset);
......
...@@ -189,6 +189,11 @@ enum as ...@@ -189,6 +189,11 @@ enum as
ACLZ, ACLZ,
AMULWT,
AMULWB,
AMULAWT,
AMULAWB,
ALAST, ALAST,
}; };
...@@ -242,12 +247,14 @@ enum as ...@@ -242,12 +247,14 @@ enum as
#define D_SHIFT (D_NONE+19) #define D_SHIFT (D_NONE+19)
#define D_FPCR (D_NONE+20) #define D_FPCR (D_NONE+20)
#define D_REGREG (D_NONE+21) #define D_REGREG (D_NONE+21) // (reg, reg)
#define D_ADDR (D_NONE+22) #define D_ADDR (D_NONE+22)
#define D_SBIG (D_NONE+23) #define D_SBIG (D_NONE+23)
#define D_CONST2 (D_NONE+24) #define D_CONST2 (D_NONE+24)
#define D_REGREG2 (D_NONE+25) // reg, reg
/* name */ /* name */
#define D_EXTERN (D_NONE+3) #define D_EXTERN (D_NONE+3)
#define D_STATIC (D_NONE+4) #define D_STATIC (D_NONE+4)
......
...@@ -1806,6 +1806,19 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -1806,6 +1806,19 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
o1 |= p->to.reg << 12; o1 |= p->to.reg << 12;
o1 |= p->from.reg; o1 |= p->from.reg;
break; break;
case 98: /* MULW{T,B} Rs, Rm, Rd */
o1 = oprrr(p->as, p->scond);
o1 |= p->to.reg << 16;
o1 |= p->from.reg << 8;
o1 |= p->reg;
break;
case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */
o1 = oprrr(p->as, p->scond);
o1 |= p->to.reg << 12;
o1 |= p->from.reg << 8;
o1 |= p->reg;
o1 |= p->to.offset << 16;
break;
} }
out[0] = o1; out[0] = o1;
...@@ -1967,6 +1980,15 @@ oprrr(int a, int sc) ...@@ -1967,6 +1980,15 @@ oprrr(int a, int sc)
case ACLZ: case ACLZ:
// CLZ doesn't support .S // CLZ doesn't support .S
return (o & (0xf<<28)) | (0x16f<<16) | (0xf1<<4); return (o & (0xf<<28)) | (0x16f<<16) | (0xf1<<4);
case AMULWT:
return (o & (0xf<<28)) | (0x12 << 20) | (0xe<<4);
case AMULWB:
return (o & (0xf<<28)) | (0x12 << 20) | (0xa<<4);
case AMULAWT:
return (o & (0xf<<28)) | (0x12 << 20) | (0xc<<4);
case AMULAWB:
return (o & (0xf<<28)) | (0x12 << 20) | (0x8<<4);
} }
diag("bad rrr %d", a); diag("bad rrr %d", a);
prasm(curp); prasm(curp);
......
...@@ -212,6 +212,7 @@ enum ...@@ -212,6 +212,7 @@ enum
C_NONE = 0, C_NONE = 0,
C_REG, C_REG,
C_REGREG, C_REGREG,
C_REGREG2,
C_SHIFT, C_SHIFT,
C_FREG, C_FREG,
C_PSR, C_PSR,
......
...@@ -225,6 +225,12 @@ Dconv(Fmt *fp) ...@@ -225,6 +225,12 @@ Dconv(Fmt *fp)
snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg); snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
break; break;
case D_REGREG2:
snprint(str, sizeof str, "R%d,R%d", a->reg, (int)a->offset);
if(a->name != D_NONE || a->sym != S)
snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
break;
case D_FREG: case D_FREG:
snprint(str, sizeof str, "F%d", a->reg); snprint(str, sizeof str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != S) if(a->name != D_NONE || a->sym != S)
...@@ -438,6 +444,7 @@ cnames[] = ...@@ -438,6 +444,7 @@ cnames[] =
[C_RCON] = "C_RCON", [C_RCON] = "C_RCON",
[C_REG] = "C_REG", [C_REG] = "C_REG",
[C_REGREG] = "C_REGREG", [C_REGREG] = "C_REGREG",
[C_REGREG2] = "C_REGREG2",
[C_ROREG] = "C_ROREG", [C_ROREG] = "C_ROREG",
[C_SAUTO] = "C_SAUTO", [C_SAUTO] = "C_SAUTO",
[C_SBRA] = "C_SBRA", [C_SBRA] = "C_SBRA",
......
...@@ -338,6 +338,7 @@ zaddr(Biobuf *f, Adr *a, Sym *h[]) ...@@ -338,6 +338,7 @@ zaddr(Biobuf *f, Adr *a, Sym *h[])
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
a->offset = BGETC(f); a->offset = BGETC(f);
break; break;
......
...@@ -103,6 +103,7 @@ Optab optab[] = ...@@ -103,6 +103,7 @@ Optab optab[] =
{ ADIV, C_REG, C_NONE, C_REG, 16, 4, 0 }, { ADIV, C_REG, C_NONE, C_REG, 16, 4, 0 },
{ AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0 }, { AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0 },
{ AMULA, C_REG, C_REG, C_REGREG2, 17, 4, 0 },
{ AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP }, { AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP },
{ AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0 }, { AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0 },
...@@ -238,5 +239,8 @@ Optab optab[] = ...@@ -238,5 +239,8 @@ Optab optab[] =
{ ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0 }, { ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0 },
{ AMULWT, C_REG, C_REG, C_REG, 98, 4, 0 },
{ AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0 },
{ AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 }, { AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 },
}; };
...@@ -447,6 +447,9 @@ aclass(Adr *a) ...@@ -447,6 +447,9 @@ aclass(Adr *a)
case D_REGREG: case D_REGREG:
return C_REGREG; return C_REGREG;
case D_REGREG2:
return C_REGREG2;
case D_SHIFT: case D_SHIFT:
return C_SHIFT; return C_SHIFT;
...@@ -835,12 +838,20 @@ buildop(void) ...@@ -835,12 +838,20 @@ buildop(void)
break; break;
case AMULL: case AMULL:
oprange[AMULA] = oprange[r];
oprange[AMULAL] = oprange[r]; oprange[AMULAL] = oprange[r];
oprange[AMULLU] = oprange[r]; oprange[AMULLU] = oprange[r];
oprange[AMULALU] = oprange[r]; oprange[AMULALU] = oprange[r];
break; break;
case AMULWT:
oprange[AMULWB] = oprange[r];
break;
case AMULAWT:
oprange[AMULAWB] = oprange[r];
break;
case AMULA:
case ALDREX: case ALDREX:
case ASTREX: case ASTREX:
case ALDREXD: case ALDREXD:
......
...@@ -124,6 +124,7 @@ addr(Biobuf *bp) ...@@ -124,6 +124,7 @@ addr(Biobuf *bp)
case D_FPCR: case D_FPCR:
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
Bgetc(bp); Bgetc(bp);
break; break;
case D_CONST2: case D_CONST2:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment