Interpreter fixes according to EM testsuit.

This commit is contained in:
carl 2019-06-16 01:20:53 +08:00
commit 3133141a08
3 changed files with 59 additions and 10 deletions

View file

@ -58,12 +58,13 @@ PRIVATE void arr(int type, /* operation TYPE */
{ {
register ptr desc = dppop(); /* array DESCriptor */ register ptr desc = dppop(); /* array DESCriptor */
register size obj_size; /* OBJect SIZE */ register size obj_size; /* OBJect SIZE */
register long diff = /* between index and lower bound */ long index = spop(elm_size);
spop(elm_size) - mem_lds(desc, elm_size); long diff = /* between index and lower bound */
index - mem_lds(desc, elm_size);
register ptr arr_addr = dppop();/* ARRay ADDRess */ register ptr arr_addr = dppop();/* ARRay ADDRess */
if (must_test && !(IgnMask&BIT(EARRAY))) { if (must_test && !(IgnMask&BIT(EARRAY))) {
if (diff < 0 || diff > mem_lds(desc + elm_size, elm_size)) { if (diff < 0 || index > mem_lds(desc + elm_size, elm_size)) {
trap(EARRAY); trap(EARRAY);
} }
} }

View file

@ -14,7 +14,7 @@
#include "text.h" #include "text.h"
#include "fra.h" #include "fra.h"
PRIVATE long adi(long, long, size), sbi(long, long, size), dvi(long, long); PRIVATE long adi(long, long, size), sbi(long, long, size), dvi(long, long, size);
PRIVATE long mli(long, long, size), rmi(long, long), ngi(long, size); PRIVATE long mli(long, long, size), rmi(long, long), ngi(long, size);
PRIVATE long sli(long, long, size), sri(long, long, size); PRIVATE long sli(long, long, size), sri(long, long, size);
@ -55,7 +55,7 @@ void DoDVI(register size l)
LOG(("@I6 DoDVI(%ld)", l)); LOG(("@I6 DoDVI(%ld)", l));
spoilFRA(); spoilFRA();
npush(dvi(spop(l), t), l); npush(dvi(spop(l), t, l), l);
} }
/** RMI w: Remainder (*) */ /** RMI w: Remainder (*) */
@ -162,7 +162,7 @@ PRIVATE long mli(long w1, long w2, size nbytes)
return (w1 * w2); return (w1 * w2);
} }
PRIVATE long dvi(long w1, long w2) PRIVATE long dvi(long w1, long w2, size nbytes)
{ {
if (w2 == 0) { if (w2 == 0) {
if (!(IgnMask&BIT(EIDIVZ))) { if (!(IgnMask&BIT(EIDIVZ))) {
@ -170,6 +170,20 @@ PRIVATE long dvi(long w1, long w2)
} }
else return (0L); else return (0L);
} }
/* Check for division overflow. */
if ((w1 == i_mins(nbytes)) && (w2 == -1))
{
if (must_test && !(IgnMask&BIT(EIOVFL)))
{
trap(EIOVFL);
} else return i_mins(nbytes);
}
if (must_test && !(IgnMask&BIT(EIOVFL)))
{
}
return (w1 / w2); return (w1 / w2);
} }
@ -212,11 +226,24 @@ PRIVATE long sli(long w1, long w2, size nbytes)
if (!(IgnMask&BIT(EIOVFL))) { if (!(IgnMask&BIT(EIOVFL))) {
/* check overflow */ /* check overflow */
if ( (w1 >= 0 && (w1 >> (nbytes*8 - w2)) != 0)
|| (w1 < 0 && (w1 >> (nbytes*8 - w2)) != -1) /* If the value is positive, then check, this is taken
) { * from rule INT32-C of SEI website.
*/
if ((w1 >= 0) && (w1 > (i_maxs(nbytes) >> w2)))
{
trap(EIOVFL); trap(EIOVFL);
} }
if ((w1 < 0) && (w1 < (i_mins(nbytes) >> w2)))
{
trap(EIOVFL);
}
/* if ((w1 < 0) && (w2 != 0) && ((w1 >> (nbytes*8 - w2)) != -1))
{
trap(EIOVFL);
}*/
} }
} }

View file

@ -45,15 +45,36 @@ extern void disassemble(void);
extern void tally(void); extern void tally(void);
extern void out_tally(void); extern void out_tally(void);
/** Check dynamically that the interpreter can run on the target machine. */
static void check_requirements(char *name)
{
/* Verify that shift right supported signed shifts. According to ISO C90,
* this is not mandatory, we should not support it here!
*/
int shrv = -4;
if ((shrv >> 1) != -2)
{
fprintf(stderr,
"%s compiled with compiler that does not support signed right shifts. Aborted.",
name);
exit(1);
}
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
register int i; register int i;
register int nosetjmp = 1; register int nosetjmp = 1;
int must_disassemble = 0; int must_disassemble = 0;
int must_tally = 0; int must_tally = 0;
prog_name = argv[0]; prog_name = argv[0];
check_requirements(prog_name);
/* Initialize the EM machine */ /* Initialize the EM machine */
PreIgnMask = 0; PreIgnMask = 0;
FRALimit = FRALIMIT; FRALimit = FRALIMIT;