summaryrefslogtreecommitdiff
path: root/sys/src/cmd/8l/span.c
diff options
context:
space:
mode:
authorjpathy <jpathy@mail.nanosouffle.net>2013-05-21 23:15:13 +0530
committerjpathy <jpathy@mail.nanosouffle.net>2013-05-21 23:15:13 +0530
commit213bf5089365d00d9d40635bcfe62e197d548c1b (patch)
treef50a0a7847731cf19718ba2104e73c3fea0f0920 /sys/src/cmd/8l/span.c
parente3883b050e1784f97bd6474c6af73023fe3bbe44 (diff)
add 6(a|l) sse support to 8(a|l)
Diffstat (limited to 'sys/src/cmd/8l/span.c')
-rw-r--r--sys/src/cmd/8l/span.c105
1 files changed, 101 insertions, 4 deletions
diff --git a/sys/src/cmd/8l/span.c b/sys/src/cmd/8l/span.c
index b9f284640..f4182e391 100644
--- a/sys/src/cmd/8l/span.c
+++ b/sys/src/cmd/8l/span.c
@@ -326,7 +326,7 @@ oclass(Adr *a)
{
long v;
- if(a->type >= D_INDIR || a->index != D_NONE) {
+ if((a->type >= D_INDIR && a->type < D_M0) || a->index != D_NONE) {
if(a->index != D_NONE && a->scale == 0) {
if(a->type == D_ADDR) {
switch(a->index) {
@@ -387,6 +387,26 @@ oclass(Adr *a)
case D_F0+7:
return Yrf;
+ case D_M0+0:
+ case D_M0+1:
+ case D_M0+2:
+ case D_M0+3:
+ case D_M0+4:
+ case D_M0+5:
+ case D_M0+6:
+ case D_M0+7:
+ return Ymr;
+
+ case D_X0+0:
+ case D_X0+1:
+ case D_X0+2:
+ case D_X0+3:
+ case D_X0+4:
+ case D_X0+5:
+ case D_X0+6:
+ case D_X0+7:
+ return Yxr;
+
case D_NONE:
return Ynone;
@@ -576,7 +596,7 @@ asmand(Adr *a, int r)
v = a->offset;
t = a->type;
if(a->index != D_NONE) {
- if(t >= D_INDIR) {
+ if(t >= D_INDIR && t < D_M0) {
t -= D_INDIR;
if(t == D_NONE) {
*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
@@ -624,7 +644,13 @@ asmand(Adr *a, int r)
*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
return;
}
- if(t >= D_INDIR) {
+ if(t >= D_M0 && t <= D_X0+7) {
+ if(v)
+ goto bad;
+ *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
+ return;
+ }
+ if(t >= D_INDIR && t < D_M0) {
t -= D_INDIR;
if(t == D_NONE || D_CS <= t && t <= D_GS) {
*andptr++ = (0 << 6) | (5 << 0) | (r << 3);
@@ -835,6 +861,30 @@ subreg(Prog *p, int from, int to)
print("%P\n", p);
}
+static int
+mediaop(Optab *o, int op, int osize, int z)
+{
+ switch(op){
+ case Pm:
+ case Pe:
+ case Pf2:
+ case Pf3:
+ if(osize != 1){
+ if(op != Pm)
+ *andptr++ = op;
+ *andptr++ = Pm;
+ op = o->op[++z];
+ break;
+ }
+ default:
+ if(andptr == and || andptr[-1] != Pm)
+ *andptr++ = Pm;
+ break;
+ }
+ *andptr++ = op;
+ return z;
+}
+
void
doasm(Prog *p)
{
@@ -851,7 +901,7 @@ doasm(Prog *p)
if(pre)
*andptr++ = pre;
- o = &optab[p->as];
+ o = opindex[p->as];
ft = oclass(&p->from) * Ymax;
tt = oclass(&p->to) * Ymax;
t = o->ytab;
@@ -872,6 +922,12 @@ found:
*andptr++ = Pm;
break;
+ case Pf2: /* xmm opcode escape */
+ case Pf3:
+ *andptr++ = o->prefix;
+ *andptr++ = Pm;
+ break;
+
case Pm: /* opcode escape */
*andptr++ = Pm;
break;
@@ -903,6 +959,30 @@ found:
asmand(&p->from, reg[p->to.type]);
break;
+ case Zm_r_xm:
+ mediaop(o, op, t[3], z);
+ asmand(&p->from, reg[p->to.type]);
+ break;
+
+ case Zm_r_i_xm:
+ mediaop(o, op, t[3], z);
+ asmand(&p->from, reg[p->to.type]);
+ *andptr++ = p->to.offset;
+ break;
+
+ case Zm_r_3d:
+ *andptr++ = 0x0f;
+ *andptr++ = 0x0f;
+ asmand(&p->from, reg[p->to.type]);
+ *andptr++ = op;
+ break;
+
+ case Zibm_r:
+ *andptr++ = op;
+ asmand(&p->from, reg[p->to.type]);
+ *andptr++ = p->to.offset;
+ break;
+
case Zaut_r:
*andptr++ = 0x8d; /* leal */
if(p->from.type != D_ADDR)
@@ -924,6 +1004,17 @@ found:
asmand(&p->to, reg[p->from.type]);
break;
+ case Zr_m_xm:
+ mediaop(o, op, t[3], z);
+ asmand(&p->to, reg[p->from.type]);
+ break;
+
+ case Zr_m_i_xm:
+ mediaop(o, op, t[3], z);
+ asmand(&p->to, reg[p->from.type]);
+ *andptr++ = p->from.offset;
+ break;
+
case Zo_m:
*andptr++ = op;
asmand(&p->to, o->op[z+1]);
@@ -942,6 +1033,12 @@ found:
*andptr++ = v;
break;
+ case Zibo_m_xm:
+ z = mediaop(o, op, t[3], z);
+ asmand(&p->to, o->op[z+1]);
+ *andptr++ = v;
+ break;
+
case Z_ib:
v = vaddr(&p->to);
case Zib_: