aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Backman <kaib@golang.org>2010-08-06 16:57:49 -0700
committerRuss Cox <rsc@golang.org>2010-08-06 16:57:49 -0700
commitdf88fc610975b0be07a1cd49199eb9917a7748e3 (patch)
treebabf460fd1d11779ffebdfdb028d5ca19390a166
parentc8c2bdbc59900a1641c08dc09abfdf6d1b3c873a (diff)
downloadgo-df88fc610975b0be07a1cd49199eb9917a7748e3.tar.gz
go-df88fc610975b0be07a1cd49199eb9917a7748e3.zip
arm: bugfixes and syscall
- integer divide by zero raises panic - float comparisons involving NaNs work - syscall interface actually handles return values and errno correctly. R=rsc, bradfitzpatrick CC=golang-dev https://golang.org/cl/1847047
-rw-r--r--src/cmd/5g/cgen.c11
-rw-r--r--src/pkg/runtime/arm/vlop.s2
-rw-r--r--src/pkg/runtime/arm/vlrt.c817
-rw-r--r--src/pkg/syscall/asm_linux_arm.s47
-rw-r--r--test/arm-pass.txt4
5 files changed, 467 insertions, 414 deletions
diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c
index b0c9b88da4..310ea99c5b 100644
--- a/src/cmd/5g/cgen.c
+++ b/src/cmd/5g/cgen.c
@@ -1044,7 +1044,16 @@ bgen(Node *n, int true, Prog *to)
cgen(nr, &n2);
gcmp(optoas(OCMP, nr->type), &n1, &n2);
- patch(gbranch(a, nr->type), to);
+ if(isfloat[nl->type->etype]) {
+ p1 = gbranch(ABVS, nr->type);
+ patch(gbranch(a, nr->type), to);
+ if(n->op == ONE)
+ patch(p1, to);
+ else
+ patch(p1, pc);
+ } else {
+ patch(gbranch(a, nr->type), to);
+ }
regfree(&n1);
regfree(&n2);
diff --git a/src/pkg/runtime/arm/vlop.s b/src/pkg/runtime/arm/vlop.s
index c9e7090fc0..f95f0f1d89 100644
--- a/src/pkg/runtime/arm/vlop.s
+++ b/src/pkg/runtime/arm/vlop.s
@@ -62,7 +62,7 @@ TEXT save<>(SB), 7, $0
MOVW 20(FP), R(D) /* denominator */
CMP $0, R(D)
BNE s1
- SWI 0
+ BL panicdivide(SB)
/* MOVW -1(R(D)), R(TMP) /* divide by zero fault */
s1: RET
diff --git a/src/pkg/runtime/arm/vlrt.c b/src/pkg/runtime/arm/vlrt.c
index 76b777a354..51ae15baa4 100644
--- a/src/pkg/runtime/arm/vlrt.c
+++ b/src/pkg/runtime/arm/vlrt.c
@@ -23,6 +23,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+// declared here to avoid include of runtime.h
+void panicstring(char*);
+
typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned short ushort;
@@ -31,6 +34,12 @@ typedef signed char schar;
#define SIGN(n) (1UL<<(n-1))
+void
+panicdivide(void)
+{
+ panicstring("integer divide by zero");
+}
+
typedef struct Vlong Vlong;
struct Vlong
{
@@ -47,8 +56,8 @@ struct Vlong
ushort loms;
ushort hils;
ushort hims;
- };
- };
+ };
+ };
};
void abort(void);
@@ -56,90 +65,90 @@ void abort(void);
void
_addv(Vlong *r, Vlong a, Vlong b)
{
- ulong lo, hi;
+ ulong lo, hi;
- lo = a.lo + b.lo;
- hi = a.hi + b.hi;
- if(lo < a.lo)
- hi++;
- r->lo = lo;
- r->hi = hi;
+ lo = a.lo + b.lo;
+ hi = a.hi + b.hi;
+ if(lo < a.lo)
+ hi++;
+ r->lo = lo;
+ r->hi = hi;
}
void
_subv(Vlong *r, Vlong a, Vlong b)
{
- ulong lo, hi;
+ ulong lo, hi;
- lo = a.lo - b.lo;
- hi = a.hi - b.hi;
- if(lo > a.lo)
- hi--;
- r->lo = lo;
- r->hi = hi;
+ lo = a.lo - b.lo;
+ hi = a.hi - b.hi;
+ if(lo > a.lo)
+ hi--;
+ r->lo = lo;
+ r->hi = hi;
}
void
_d2v(Vlong *y, double d)
{
- union { double d; struct Vlong; } x;
- ulong xhi, xlo, ylo, yhi;
- int sh;
-
- x.d = d;
-
- xhi = (x.hi & 0xfffff) | 0x100000;
- xlo = x.lo;
- sh = 1075 - ((x.hi >> 20) & 0x7ff);
-
- ylo = 0;
- yhi = 0;
- if(sh >= 0) {
- /* v = (hi||lo) >> sh */
- if(sh < 32) {
- if(sh == 0) {
- ylo = xlo;
- yhi = xhi;
- } else {
- ylo = (xlo >> sh) | (xhi << (32-sh));
- yhi = xhi >> sh;
- }
- } else {
- if(sh == 32) {
- ylo = xhi;
- } else
- if(sh < 64) {
- ylo = xhi >> (sh-32);
- }
- }
- } else {
- /* v = (hi||lo) << -sh */
- sh = -sh;
- if(sh <= 10) {
- ylo = xlo << sh;
- yhi = (xhi << sh) | (xlo >> (32-sh));
- } else {
- /* overflow */
- yhi = d; /* causes something awful */
- }
- }
- if(x.hi & SIGN(32)) {
- if(ylo != 0) {
- ylo = -ylo;
- yhi = ~yhi;
- } else
- yhi = -yhi;
- }
-
- y->hi = yhi;
- y->lo = ylo;
+ union { double d; struct Vlong; } x;
+ ulong xhi, xlo, ylo, yhi;
+ int sh;
+
+ x.d = d;
+
+ xhi = (x.hi & 0xfffff) | 0x100000;
+ xlo = x.lo;
+ sh = 1075 - ((x.hi >> 20) & 0x7ff);
+
+ ylo = 0;
+ yhi = 0;
+ if(sh >= 0) {
+ /* v = (hi||lo) >> sh */
+ if(sh < 32) {
+ if(sh == 0) {
+ ylo = xlo;
+ yhi = xhi;
+ } else {
+ ylo = (xlo >> sh) | (xhi << (32-sh));
+ yhi = xhi >> sh;
+ }
+ } else {
+ if(sh == 32) {
+ ylo = xhi;
+ } else
+ if(sh < 64) {
+ ylo = xhi >> (sh-32);
+ }
+ }
+ } else {
+ /* v = (hi||lo) << -sh */
+ sh = -sh;
+ if(sh <= 10) {
+ ylo = xlo << sh;
+ yhi = (xhi << sh) | (xlo >> (32-sh));
+ } else {
+ /* overflow */
+ yhi = d; /* causes something awful */
+ }
+ }
+ if(x.hi & SIGN(32)) {
+ if(ylo != 0) {
+ ylo = -ylo;
+ yhi = ~yhi;
+ } else
+ yhi = -yhi;
+ }
+
+ y->hi = yhi;
+ y->lo = ylo;
}
void
_f2v(Vlong *y, float f)
{
- _d2v(y, f);
+ _d2v(y, f);
}
void
@@ -151,21 +160,21 @@ void
double
_v2d(Vlong x)
{
- if(x.hi & SIGN(32)) {
- if(x.lo) {
- x.lo = -x.lo;
- x.hi = ~x.hi;
- } else
- x.hi = -x.hi;
- return -((long)x.hi*4294967296. + x.lo);
- }
- return (long)x.hi*4294967296. + x.lo;
+ if(x.hi & SIGN(32)) {
+ if(x.lo) {
+ x.lo = -x.lo;
+ x.hi = ~x.hi;
+ } else
+ x.hi = -x.hi;
+ return -((long)x.hi*4294967296. + x.lo);
+ }
+ return (long)x.hi*4294967296. + x.lo;
}
float
_v2f(Vlong x)
{
- return _v2d(x);
+ return _v2d(x);
}
void
@@ -178,75 +187,75 @@ void
static void
dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
{
- ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
- int i;
-
- numhi = num.hi;
- numlo = num.lo;
- denhi = den.hi;
- denlo = den.lo;
-
- /*
- * get a divide by zero
- */
- if(denlo==0 && denhi==0) {
- numlo = numlo / denlo;
- }
-
- /*
- * set up the divisor and find the number of iterations needed
- */
- if(numhi >= SIGN(32)) {
- quohi = SIGN(32);
- quolo = 0;
- } else {
- quohi = numhi;
- quolo = numlo;
- }
- i = 0;
- while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
- denhi = (denhi<<1) | (denlo>>31);
- denlo <<= 1;
- i++;
- }
-
- quohi = 0;
- quolo = 0;
- for(; i >= 0; i--) {
- quohi = (quohi<<1) | (quolo>>31);
- quolo <<= 1;
- if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
- t = numlo;
- numlo -= denlo;
- if(numlo > t)
- numhi--;
- numhi -= denhi;
- quolo |= 1;
- }
- denlo = (denlo>>1) | (denhi<<31);
- denhi >>= 1;
- }
-
- if(q) {
- q->lo = quolo;
- q->hi = quohi;
- }
- if(r) {
- r->lo = numlo;
- r->hi = numhi;
- }
+ ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
+ int i;
+
+ numhi = num.hi;
+ numlo = num.lo;
+ denhi = den.hi;
+ denlo = den.lo;
+
+ /*
+ * get a divide by zero
+ */
+ if(denlo==0 && denhi==0) {
+ panicdivide();
+ }
+
+ /*
+ * set up the divisor and find the number of iterations needed
+ */
+ if(numhi >= SIGN(32)) {
+ quohi = SIGN(32);
+ quolo = 0;
+ } else {
+ quohi = numhi;
+ quolo = numlo;
+ }
+ i = 0;
+ while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
+ denhi = (denhi<<1) | (denlo>>31);
+ denlo <<= 1;
+ i++;
+ }
+
+ quohi = 0;
+ quolo = 0;
+ for(; i >= 0; i--) {
+ quohi = (quohi<<1) | (quolo>>31);
+ quolo <<= 1;
+ if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
+ t = numlo;
+ numlo -= denlo;
+ if(numlo > t)
+ numhi--;
+ numhi -= denhi;
+ quolo |= 1;
+ }
+ denlo = (denlo>>1) | (denhi<<31);
+ denhi >>= 1;
+ }
+
+ if(q) {
+ q->lo = quolo;
+ q->hi = quohi;
+ }
+ if(r) {
+ r->lo = numlo;
+ r->hi = numhi;
+ }
}
void
_divvu(Vlong *q, Vlong n, Vlong d)
{
- if(n.hi == 0 && d.hi == 0) {
- q->hi = 0;
- q->lo = n.lo / d.lo;
- return;
- }
- dodiv(n, d, q, 0);
+ if(n.hi == 0 && d.hi == 0) {
+ q->hi = 0;
+ q->lo = n.lo / d.lo;
+ return;
+ }
+ dodiv(n, d, q, 0);
}
void
@@ -259,12 +268,12 @@ void
_modvu(Vlong *r, Vlong n, Vlong d)
{
- if(n.hi == 0 && d.hi == 0) {
- r->hi = 0;
- r->lo = n.lo % d.lo;
- return;
- }
- dodiv(n, d, 0, r);
+ if(n.hi == 0 && d.hi == 0) {
+ r->hi = 0;
+ r->lo = n.lo % d.lo;
+ return;
+ }
+ dodiv(n, d, 0, r);
}
void
@@ -277,20 +286,20 @@ static void
vneg(Vlong *v)
{
- if(v->lo == 0) {
- v->hi = -v->hi;
- return;
- }
- v->lo = -v->lo;
- v->hi = ~v->hi;
+ if(v->lo == 0) {
+ v->hi = -v->hi;
+ return;
+ }
+ v->lo = -v->lo;
+ v->hi = ~v->hi;
}
void
_divv(Vlong *q, Vlong n, Vlong d)
{
- long nneg, dneg;
+ long nneg, dneg;
- if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
+ if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
if((long)n.lo == -0x80000000 && (long)d.lo == -1) {
// special case: 32-bit -0x80000000 / -1 causes wrong sign
q->lo = 0x80000000;
@@ -300,16 +309,16 @@ _divv(Vlong *q, Vlong n, Vlong d)
q->lo = (long)n.lo / (long)d.lo;
q->hi = ((long)q->lo) >> 31;
return;
- }
- nneg = n.hi >> 31;
- if(nneg)
- vneg(&n);
- dneg = d.hi >> 31;
- if(dneg)
- vneg(&d);
- dodiv(n, d, q, 0);
- if(nneg != dneg)
- vneg(q);
+ }
+ nneg = n.hi >> 31;
+ if(nneg)
+ vneg(&n);
+ dneg = d.hi >> 31;
+ if(dneg)
+ vneg(&d);
+ dodiv(n, d, q, 0);
+ if(nneg != dneg)
+ vneg(q);
}
void
@@ -321,22 +330,22 @@ void
void
_modv(Vlong *r, Vlong n, Vlong d)
{
- long nneg, dneg;
+ long nneg, dneg;
- if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
- r->lo = (long)n.lo % (long)d.lo;
- r->hi = ((long)r->lo) >> 31;
- return;
- }
- nneg = n.hi >> 31;
- if(nneg)
- vneg(&n);
- dneg = d.hi >> 31;
- if(dneg)
- vneg(&d);
- dodiv(n, d, 0, r);
- if(nneg)
- vneg(r);
+ if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
+ r->lo = (long)n.lo % (long)d.lo;
+ r->hi = ((long)r->lo) >> 31;
+ return;
+ }
+ nneg = n.hi >> 31;
+ if(nneg)
+ vneg(&n);
+ dneg = d.hi >> 31;
+ if(dneg)
+ vneg(&d);
+ dodiv(n, d, 0, r);
+ if(nneg)
+ vneg(r);
}
void
@@ -348,439 +357,439 @@ void
void
_rshav(Vlong *r, Vlong a, int b)
{
- long t;
-
- t = a.hi;
- if(b >= 32) {
- r->hi = t>>31;
- if(b >= 64) {
- /* this is illegal re C standard */
- r->lo = t>>31;
- return;
- }
- r->lo = t >> (b-32);
- return;
- }
- if(b <= 0) {
- r->hi = t;
- r->lo = a.lo;
- return;
- }
- r->hi = t >> b;
- r->lo = (t << (32-b)) | (a.lo >> b);
+ long t;
+
+ t = a.hi;
+ if(b >= 32) {
+ r->hi = t>>31;
+ if(b >= 64) {
+ /* this is illegal re C standard */
+ r->lo = t>>31;
+ return;
+ }
+ r->lo = t >> (b-32);
+ return;
+ }
+ if(b <= 0) {
+ r->hi = t;
+ r->lo = a.lo;
+ return;
+ }
+ r->hi = t >> b;
+ r->lo = (t << (32-b)) | (a.lo >> b);
}
void
_rshlv(Vlong *r, Vlong a, int b)
{
- ulong t;
-
- t = a.hi;
- if(b >= 32) {
- r->hi = 0;
- if(b >= 64) {
- /* this is illegal re C standard */
- r->lo = 0;
- return;
- }
- r->lo = t >> (b-32);
- return;
- }
- if(b <= 0) {
- r->hi = t;
- r->lo = a.lo;
- return;
- }
- r->hi = t >> b;
- r->lo = (t << (32-b)) | (a.lo >> b);
+ ulong t;
+
+ t = a.hi;
+ if(b >= 32) {
+ r->hi = 0;
+ if(b >= 64) {
+ /* this is illegal re C standard */
+ r->lo = 0;
+ return;
+ }
+ r->lo = t >> (b-32);
+ return;
+ }
+ if(b <= 0) {
+ r->hi = t;
+ r->lo = a.lo;
+ return;
+ }
+ r->hi = t >> b;
+ r->lo = (t << (32-b)) | (a.lo >> b);
}
void
_lshv(Vlong *r, Vlong a, int b)
{
- ulong t;
-
- t = a.lo;
- if(b >= 32) {
- r->lo = 0;
- if(b >= 64) {
- /* this is illegal re C standard */
- r->hi = 0;
- return;
- }
- r->hi = t << (b-32);
- return;
- }
- if(b <= 0) {
- r->lo = t;
- r->hi = a.hi;
- return;
- }
- r->lo = t << b;
- r->hi = (t >> (32-b)) | (a.hi << b);
+ ulong t;
+
+ t = a.lo;
+ if(b >= 32) {
+ r->lo = 0;
+ if(b >= 64) {
+ /* this is illegal re C standard */
+ r->hi = 0;
+ return;
+ }
+ r->hi = t << (b-32);
+ return;
+ }
+ if(b <= 0) {
+ r->lo = t;
+ r->hi = a.hi;
+ return;
+ }
+ r->lo = t << b;
+ r->hi = (t >> (32-b)) | (a.hi << b);
}
void
_andv(Vlong *r, Vlong a, Vlong b)
{
- r->hi = a.hi & b.hi;
- r->lo = a.lo & b.lo;
+ r->hi = a.hi & b.hi;
+ r->lo = a.lo & b.lo;
}
void
_orv(Vlong *r, Vlong a, Vlong b)
{
- r->hi = a.hi | b.hi;
- r->lo = a.lo | b.lo;
+ r->hi = a.hi | b.hi;
+ r->lo = a.lo | b.lo;
}
void
_xorv(Vlong *r, Vlong a, Vlong b)
{
- r->hi = a.hi ^ b.hi;
- r->lo = a.lo ^ b.lo;
+ r->hi = a.hi ^ b.hi;
+ r->lo = a.lo ^ b.lo;
}
void
_vpp(Vlong *l, Vlong *r)
{
- l->hi = r->hi;
- l->lo = r->lo;
- r->lo++;
- if(r->lo == 0)
- r->hi++;
+ l->hi = r->hi;
+ l->lo = r->lo;
+ r->lo++;
+ if(r->lo == 0)
+ r->hi++;
}
void
_vmm(Vlong *l, Vlong *r)
{
- l->hi = r->hi;
- l->lo = r->lo;
- if(r->lo == 0)
- r->hi--;
- r->lo--;
+ l->hi = r->hi;
+ l->lo = r->lo;
+ if(r->lo == 0)
+ r->hi--;
+ r->lo--;
}
void
_ppv(Vlong *l, Vlong *r)
{
- r->lo++;
- if(r->lo == 0)
- r->hi++;
- l->hi = r->hi;
- l->lo = r->lo;
+ r->lo++;
+ if(r->lo == 0)
+ r->hi++;
+ l->hi = r->hi;
+ l->lo = r->lo;
}
void
_mmv(Vlong *l, Vlong *r)
{
- if(r->lo == 0)
- r->hi--;
- r->lo--;
- l->hi = r->hi;
- l->lo = r->lo;
+ if(r->lo == 0)
+ r->hi--;
+ r->lo--;
+ l->hi = r->hi;
+ l->lo = r->lo;
}
void
_vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
{
- Vlong t, u;
-
- u = *ret;
- switch(type) {
- default:
- abort();
- break;
-
- case 1: /* schar */
- t.lo = *(schar*)lv;
- t.hi = t.lo >> 31;
- fn(&u, t, rv);
- *(schar*)lv = u.lo;
- break;
-
- case 2: /* uchar */
- t.lo = *(uchar*)lv;
- t.hi = 0;
- fn(&u, t, rv);
- *(uchar*)lv = u.lo;
- break;
-
- case 3: /* short */
- t.lo = *(short*)lv;
- t.hi = t.lo >> 31;
- fn(&u, t, rv);
- *(short*)lv = u.lo;
- break;
-
- case 4: /* ushort */
- t.lo = *(ushort*)lv;
- t.hi = 0;
- fn(&u, t, rv);
- *(ushort*)lv = u.lo;
- break;
-
- case 9: /* int */
- t.lo = *(int*)lv;
- t.hi = t.lo >> 31;
- fn(&u, t, rv);
- *(int*)lv = u.lo;
- break;
-
- case 10: /* uint */
- t.lo = *(uint*)lv;
- t.hi = 0;
- fn(&u, t, rv);
- *(uint*)lv = u.lo;
- break;
-
- case 5: /* long */
- t.lo = *(long*)lv;
- t.hi = t.lo >> 31;
- fn(&u, t, rv);
- *(long*)lv = u.lo;
- break;
-
- case 6: /* ulong */
- t.lo = *(ulong*)lv;
- t.hi = 0;
- fn(&u, t, rv);
- *(ulong*)lv = u.lo;
- break;
-
- case 7: /* vlong */
- case 8: /* uvlong */
- fn(&u, *(Vlong*)lv, rv);
- *(Vlong*)lv = u;
- break;
- }
- *ret = u;
+ Vlong t, u;
+
+ u = *ret;
+ switch(type) {
+ default:
+ abort();
+ break;
+
+ case 1: /* schar */
+ t.lo = *(schar*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(schar*)lv = u.lo;
+ break;
+
+ case 2: /* uchar */
+ t.lo = *(uchar*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(uchar*)lv = u.lo;
+ break;
+
+ case 3: /* short */
+ t.lo = *(short*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(short*)lv = u.lo;
+ break;
+
+ case 4: /* ushort */
+ t.lo = *(ushort*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(ushort*)lv = u.lo;
+ break;
+
+ case 9: /* int */
+ t.lo = *(int*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(int*)lv = u.lo;
+ break;
+
+ case 10: /* uint */
+ t.lo = *(uint*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(uint*)lv = u.lo;
+ break;
+
+ case 5: /* long */
+ t.lo = *(long*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(long*)lv = u.lo;
+ break;
+
+ case 6: /* ulong */
+ t.lo = *(ulong*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(ulong*)lv = u.lo;
+ break;
+
+ case 7: /* vlong */
+ case 8: /* uvlong */
+ fn(&u, *(Vlong*)lv, rv);
+ *(Vlong*)lv = u;
+ break;
+ }
+ *ret = u;
}
void
_p2v(Vlong *ret, void *p)
{
- long t;
+ long t;
- t = (ulong)p;
- ret->lo = t;
- ret->hi = 0;
+ t = (ulong)p;
+ ret->lo = t;
+ ret->hi = 0;
}
void
_sl2v(Vlong *ret, long sl)
{
- long t;
+ long t;
- t = sl;
- ret->lo = t;
- ret->hi = t >> 31;
+ t = sl;
+ ret->lo = t;
+ ret->hi = t >> 31;
}
void
_ul2v(Vlong *ret, ulong ul)
{
- long t;
+ long t;
- t = ul;
- ret->lo = t;
- ret->hi = 0;
+ t = ul;
+ ret->lo = t;
+ ret->hi = 0;
}
void
_si2v(Vlong *ret, int si)
{
- long t;
+ long t;
- t = si;
- ret->lo = t;
- ret->hi = t >> 31;
+ t = si;
+ ret->lo = t;
+ ret->hi = t >> 31;
}
void
_ui2v(Vlong *ret, uint ui)
{
- long t;
+ long t;
- t = ui;
- ret->lo = t;
- ret->hi = 0;
+ t = ui;
+ ret->lo = t;
+ ret->hi = 0;
}
void
_sh2v(Vlong *ret, long sh)
{
- long t;
+ long t;
- t = (sh << 16) >> 16;
- ret->lo = t;
- ret->hi = t >> 31;
+ t = (sh << 16) >> 16;
+ ret->lo = t;
+ ret->hi = t >> 31;
}
void
_uh2v(Vlong *ret, ulong ul)
{
- long t;
+ long t;
- t = ul & 0xffff;
- ret->lo = t;
- ret->hi = 0;
+ t = ul & 0xffff;
+ ret->lo = t;
+ ret->hi = 0;
}
void
_sc2v(Vlong *ret, long uc)
{
- long t;
+ long t;
- t = (uc << 24) >> 24;
- ret->lo = t;
- ret->hi = t >> 31;
+ t = (uc << 24) >> 24;
+ ret->lo = t;
+ ret->hi = t >> 31;
}
void
_uc2v(Vlong *ret, ulong ul)
{
- long t;
+ long t;
- t = ul & 0xff;
- ret->lo = t;
- ret->hi = 0;
+ t = ul & 0xff;
+ ret->lo = t;
+ ret->hi = 0;
}
long
_v2sc(Vlong rv)
{
- long t;
+ long t;
- t = rv.lo & 0xff;
- return (t << 24) >> 24;
+ t = rv.lo & 0xff;
+ return (t << 24) >> 24;
}
long
_v2uc(Vlong rv)
{
- return rv.lo & 0xff;
+ return rv.lo & 0xff;
}
long
_v2sh(Vlong rv)
{
- long t;
+ long t;
- t = rv.lo & 0xffff;
- return (t << 16) >> 16;
+ t = rv.lo & 0xffff;
+ return (t << 16) >> 16;
}
long
_v2uh(Vlong rv)
{
- return rv.lo & 0xffff;
+ return rv.lo & 0xffff;
}
long
_v2sl(Vlong rv)
{
- return rv.lo;
+ return rv.lo;
}
long
_v2ul(Vlong rv)
{
- return rv.lo;
+ return rv.lo;
}
long
_v2si(Vlong rv)
{
- return rv.lo;
+ return rv.lo;
}
long
_v2ui(Vlong rv)
{
- return rv.lo;
+ return rv.lo;
}
int
_testv(Vlong rv)
{
- return rv.lo || rv.hi;
+ return rv.lo || rv.hi;
}
int
_eqv(Vlong lv, Vlong rv)
{
- return lv.lo == rv.lo && lv.hi == rv.hi;
+ return lv.lo == rv.lo && lv.hi == rv.hi;
}
int
_nev(Vlong lv, Vlong rv)
{
- return lv.lo != rv.lo || lv.hi != rv.hi;
+ return lv.lo != rv.lo || lv.hi != rv.hi;
}
int
_ltv(Vlong lv, Vlong rv)
{
- return (long)lv.hi < (long)rv.hi ||
- (lv.hi == rv.hi && lv.lo < rv.lo);
+ return (long)lv.hi < (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo < rv.lo);
}
int
_lev(Vlong lv, Vlong rv)
{
- return (long)lv.hi < (long)rv.hi ||
- (lv.hi == rv.hi && lv.lo <= rv.lo);
+ return (long)lv.hi < (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo <= rv.lo);
}
int
_gtv(Vlong lv, Vlong rv)
{
- return (long)lv.hi > (long)rv.hi ||
- (lv.hi == rv.hi && lv.lo > rv.lo);
+ return (long)lv.hi > (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo > rv.lo);
}
int
_gev(Vlong lv, Vlong rv)
{
- return (long)lv.hi > (long)rv.hi ||
- (lv.hi == rv.hi && lv.lo >= rv.lo);
+ return (long)lv.hi > (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo >= rv.lo);
}
int
_lov(Vlong lv, Vlong rv)
{
- return lv.hi < rv.hi ||
- (lv.hi == rv.hi && lv.lo < rv.lo);
+ return lv.hi < rv.hi ||
+ (lv.hi == rv.hi && lv.lo < rv.lo);
}
int
_lsv(Vlong lv, Vlong rv)
{
- return lv.hi < rv.hi ||
- (lv.hi == rv.hi && lv.lo <= rv.lo);
+ return lv.hi < rv.hi ||
+ (lv.hi == rv.hi && lv.lo <= rv.lo);
}
int
_hiv(Vlong lv, Vlong rv)
{
- return lv.hi > rv.hi ||
- (lv.hi == rv.hi && lv.lo > rv.lo);
+ return lv.hi > rv.hi ||
+ (lv.hi == rv.hi && lv.lo > rv.lo);
}
int
_hsv(Vlong lv, Vlong rv)
{
- return lv.hi > rv.hi ||
- (lv.hi == rv.hi && lv.lo >= rv.lo);
+ return lv.hi > rv.hi ||
+ (lv.hi == rv.hi && lv.lo >= rv.lo);
}
diff --git a/src/pkg/syscall/asm_linux_arm.s b/src/pkg/syscall/asm_linux_arm.s
index 830d41c788..a5790885b4 100644
--- a/src/pkg/syscall/asm_linux_arm.s
+++ b/src/pkg/syscall/asm_linux_arm.s
@@ -17,9 +17,21 @@ TEXT ·Syscall(SB),7,$0
MOVW 12(SP), R1
MOVW 16(SP), R2
SWI $0
- MOVW R0, 20(SP) // r1
- MOVW R1, 24(SP) // r2
+ MOVW $0xfffff001, R1
+ CMP R1, R0
+ BLS ok
+ MOVW $-1, R1
+ MOVW R1, 20(SP) // r1
+ MOVW $0, R2
+ MOVW R2, 24(SP) // r2
+ RSB $0, R0, R0
+ MOVW R0, 28(SP) // errno
+ BL runtime·exitsyscall(SB)
+ RET
+ok:
+ MOVW R0, 20(SP) // r1
MOVW $0, R0
+ MOVW R0, 24(SP) // r2
MOVW R0, 28(SP) // errno
BL runtime·exitsyscall(SB)
RET
@@ -36,9 +48,21 @@ TEXT ·Syscall6(SB),7,$0
MOVW 24(SP), R4
MOVW 28(SP), R5
SWI $0
- MOVW R0, 32(SP) // r1
- MOVW R1, 36(SP) // r2
+ MOVW $0xfffff001, R1
+ CMP R1, R0
+ BLS ok6
+ MOVW $-1, R1
+ MOVW R1, 32(SP) // r1
+ MOVW $0, R2
+ MOVW R2, 36(SP) // r2
+ RSB $0, R0, R0
+ MOVW R0, 40(SP) // errno
+ BL runtime·exitsyscall(SB)
+ RET
+ok6:
+ MOVW R0, 32(SP) // r1
MOVW $0, R0
+ MOVW R0, 36(SP) // r2
MOVW R0, 40(SP) // errno
BL runtime·exitsyscall(SB)
RET
@@ -50,8 +74,19 @@ TEXT ·RawSyscall(SB),7,$0
MOVW 12(SP), R1
MOVW 16(SP), R2
SWI $0
- MOVW R0, 20(SP) // r1
- MOVW R1, 24(SP) // r2
+ MOVW $0xfffff001, R1
+ CMP R1, R0
+ BLS ok1
+ MOVW $-1, R1
+ MOVW R1, 20(SP) // r1
+ MOVW $0, R2
+ MOVW R2, 24(SP) // r2
+ RSB $0, R0, R0
+ MOVW R0, 28(SP) // errno
+ RET
+ok1:
+ MOVW R0, 20(SP) // r1
MOVW $0, R0
+ MOVW R0, 24(SP) // r2
MOVW R0, 28(SP) // errno
RET
diff --git a/test/arm-pass.txt b/test/arm-pass.txt
index 0a586a077b..2c7230f100 100644
--- a/test/arm-pass.txt
+++ b/test/arm-pass.txt
@@ -43,7 +43,7 @@
./env.go
./escape.go
./float_lit.go
-# ./floatcmp.go # fail, BUG
+./floatcmp.go
./for.go
./func.go
./func1.go
@@ -116,7 +116,7 @@
./varerr.go
./varinit.go
./vectors.go
-# ./zerodivide.go # fail, BUG
+./zerodivide.go
ken/array.go
ken/chan.go
ken/chan1.go