summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-05-09 10:23:23 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-05-09 10:23:23 +0200
commite8cf7530517534ccd9f5b0469191aa7c41581120 (patch)
tree5069ad580f417529a446490ff9573a92ef538526 /sys/src
parent4e7fbabfc9f33f6ea5e5a46d5d6d7532d5f68301 (diff)
7l: implement MOVP instruction
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/cmd/7l/asmout.c31
-rw-r--r--sys/src/cmd/7l/optab.c14
-rw-r--r--sys/src/cmd/7l/span.c5
3 files changed, 50 insertions, 0 deletions
diff --git a/sys/src/cmd/7l/asmout.c b/sys/src/cmd/7l/asmout.c
index 5a30d13d4..52b59f253 100644
--- a/sys/src/cmd/7l/asmout.c
+++ b/sys/src/cmd/7l/asmout.c
@@ -847,6 +847,34 @@ asmout(Prog *p, Optab *o)
o1 = omovlit(AMOV, p, &p->from, REGTMP);
o2 = olsr12u(opldr12(p->as), 0, REGTMP, p->to.reg);
break;
+
+ case 66: /* movpT (R)O!,R; movpT O(R)!, R -> ldrT */
+ o1 = opldrpp(p->as);
+ v = p->from.offset >> 2 + ((o1 & S64) != 0);
+ if(v < -128 || v > 127)
+ diag("offset out of range\n%P", p);
+ if(p->from.type == D_XPOST)
+ o1 |= 1<<23;
+ else if(p->from.type == D_XPRE)
+ o1 |= 3<<23;
+ else
+ o1 |= 2<<23;
+ o1 |= ((v&0x7F)<<15) | (p->from.reg<<5) | p->reg | (p->to.reg<<10);
+ break;
+
+ case 67: /* movpT R,(R)O!; movpT O(R)!, R -> strT */
+ o1 = LD2STR(opldrpp(p->as));
+ v = p->to.offset >> 2 + ((o1 & S64) != 0);
+ if(v < -128 || v > 127)
+ diag("offset out of range\n%P", p);
+ if(p->to.type == D_XPOST)
+ o1 |= 1<<23;
+ else if(p->to.type == D_XPRE)
+ o1 |= 3<<23;
+ else
+ o1 |= 2<<23;
+ o1 |= ((v&0x7F)<<15) | (p->to.reg<<5) | p->from.reg | (p->reg<<10);
+ break;
}
if(debug['a'] > 1)
@@ -1552,6 +1580,9 @@ opldrpp(int a)
case AMOVHU: return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22;
case AMOVB: return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22;
case AMOVBU: return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22;
+ case AMOVPW: return 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22;
+ case AMOVPSW: return 1<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22;
+ case AMOVP: return 2<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22;
}
diag("bad opldr %A\n%P", a, curp);
return 0;
diff --git a/sys/src/cmd/7l/optab.c b/sys/src/cmd/7l/optab.c
index b72c5de0c..f59187b82 100644
--- a/sys/src/cmd/7l/optab.c
+++ b/sys/src/cmd/7l/optab.c
@@ -309,6 +309,20 @@ Optab optab[] =
{ AFMOVS, C_FREG, C_NONE, C_XPRE, 23, 4, 0 },
{ AFMOVD, C_FREG, C_NONE, C_XPRE, 23, 4, 0 },
+ { AMOVP, C_PPAUTO, C_REG, C_REG, 66, 4, 0 },
+ { AMOVP, C_PPOREG, C_REG, C_REG, 66, 4, 0 },
+ { AMOVP, C_NPAUTO, C_REG, C_REG, 66, 4, 0 },
+ { AMOVP, C_NPOREG, C_REG, C_REG, 66, 4, 0 },
+ { AMOVP, C_XPOST, C_REG, C_REG, 66, 4, 0 },
+ { AMOVP, C_XPRE, C_REG, C_REG, 66, 4, 0 },
+
+ { AMOVP, C_REG, C_REG, C_PPAUTO, 67, 4, 0 },
+ { AMOVP, C_REG, C_REG, C_PPOREG, 67, 4, 0 },
+ { AMOVP, C_REG, C_REG, C_NPAUTO, 67, 4, 0 },
+ { AMOVP, C_REG, C_REG, C_NPOREG, 67, 4, 0 },
+ { AMOVP, C_REG, C_REG, C_XPOST, 67, 4, 0 },
+ { AMOVP, C_REG, C_REG, C_XPRE, 67, 4, 0 },
+
/* special */
{ AMOV, C_SPR, C_NONE, C_REG, 35, 4, 0 },
{ AMRS, C_SPR, C_NONE, C_REG, 35, 4, 0 },
diff --git a/sys/src/cmd/7l/span.c b/sys/src/cmd/7l/span.c
index fe4244099..17f57d611 100644
--- a/sys/src/cmd/7l/span.c
+++ b/sys/src/cmd/7l/span.c
@@ -1347,6 +1347,11 @@ buildop(void)
oprange[ASHA256H2] = t;
oprange[ASHA256SU1] = t;
break;
+
+ case AMOVP:
+ oprange[AMOVPW] = t;
+ oprange[AMOVPSW] = t;
+ break;
}
}
}