Commit df88fc61 authored by Kai Backman's avatar Kai Backman Committed by Russ Cox

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
parent c8c2bdbc
......@@ -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);
......
......@@ -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
......
......@@ -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);
}
......@@ -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
......@@ -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
......
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