Permalink
Browse files

Implement double deref for I&N registers

Make deref do what the spec says and make all of the ops do the appropriate
type interpretation.

Implementing deref this way (and using the current constant segment loading
method) means that the value types (I&N) need to be dereferenced twice when
loaded from the constants segment. This commit fixes that in all existing
tests.
  • Loading branch information...
1 parent 3f8ddf2 commit 48a8cc2ccfd06f772251be2a247df2f09fa1f6c3 @nbrown nbrown committed Apr 4, 2012
View
@@ -69,6 +69,9 @@ new_interp() {
M0_CallFrame *
new_call_frame( M0_Interp *interp ) {
M0_CallFrame *frame = malloc( sizeof (M0_CallFrame) );
+ unsigned int i;
+ for(i = 0; i < 256; i++)
+ frame->registers[i] = (uint64_t)0;
/* this is a silly minimal hack for now */
frame->registers[CHUNK] = (uint64_t)interp->first_chunk;
View
@@ -11,25 +11,10 @@ Copyright (C) 2011-2012, Parrot Foundation.
#include "include/m0_interp_structures.h"
#include "include/m0_compiler_defines.h"
-M0_RegisterType get_register_type(const unsigned int register_number) {
- M0_RegisterType reg_type = INVALID;
- if (register_number <= 11)
- reg_type = NAMED;
- else if (12 <= register_number && register_number <= 72)
- reg_type = INTEGER;
- else if (73 <= register_number && register_number <= 133)
- reg_type = NUMBER;
- else if (134 <= register_number && register_number <= 194)
- reg_type = STRING;
- else if (195 <= register_number && register_number <= 255)
- reg_type = POINTER;
- return reg_type;
-}
-
static void
m0_op_set_imm( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = ops[2] * 256 + ops[3];
+ frame->registers[ops[1]] = (uint64_t)(ops[2] * 256 + ops[3]);
}
static void
@@ -43,28 +28,13 @@ m0_op_deref( M0_CallFrame *frame, const unsigned char *ops )
M0_Constants_Segment *consts =
(M0_Constants_Segment *)frame->registers[ ref ];
unsigned long offset = frame->registers[ ops[3] ];
- size_t size = sizeof(uint64_t);
- int use_address = 0;
- switch ( get_register_type(ops[1])) {
- case STRING:
- case POINTER:
- use_address = 1;
- break;
- case NUMBER:
- size = 4;
- break;
- default:
- break;
- }
-
- frame->registers[ ops[1] ] = (uint64_t)0;
- if (use_address)
- memcpy(&frame->registers[ ops[1] ], &(consts->consts[offset]), size);
- else
- memcpy(&frame->registers[ ops[1] ], (consts->consts[offset]), size);
+ frame->registers[ ops[1] ] = (uint64_t)consts->consts[offset];
break;
}
default:
+ if( ops[3] == 0) {
+ frame->registers[ ops[1] ] = (*(uint64_t*)(frame->registers[ ops[2] ]));
+ }
/* XXX: the rest of the system has non-uniform array handling */
break;
}
@@ -81,56 +51,59 @@ static void
m0_op_print_i( M0_CallFrame *frame, const unsigned char *ops )
{
/* note the lack of filehandle selection (ops[1]) for output */
- fprintf( stdout, "%d", (int)frame->registers[ ops[2] ] );
+ fprintf( stdout, "%d", (unsigned int)frame->registers[ ops[2] ] );
}
static void
m0_op_add_i( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = frame->registers[ops[2]] +
- frame->registers[ops[3]];
+ unsigned int r2 = *(unsigned int*)&frame->registers[ops[2]];
+ unsigned int r3 = *(unsigned int*)&frame->registers[ops[3]];
+ unsigned int *result = (unsigned int*) &(frame->registers[ops[1]]);
+ *result = r2 + r3;
}
static void
m0_op_add_n( M0_CallFrame *frame, const unsigned char *ops )
{
- float *r2 = (float*) &(frame->registers[ops[2]]);
- float *r3 = (float*) &(frame->registers[ops[3]]);
- float *result = (float*) &(frame->registers[ops[1]]);
- frame->registers[ops[1]] = (uint64_t)0;
- *result = *r2 + *r3;
+ double r2 = *(double*)&frame->registers[ops[2]];
+ double r3 = *(double*)&frame->registers[ops[3]];
+ double *result = (double*) &(frame->registers[ops[1]]);
+ *result = r2 + r3;
}
static void
m0_op_sub_i( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = frame->registers[ops[2]] -
- frame->registers[ops[3]];
+ unsigned int r2 = *(unsigned int*)&frame->registers[ops[2]];
+ unsigned int r3 = *(unsigned int*)&frame->registers[ops[3]];
+ unsigned int *result = (unsigned int*) &(frame->registers[ops[1]]);
+ unsigned int temp_result = r2 - r3;
+ frame->registers[ops[1]] = (uint16_t)0;
+ *result = temp_result;
}
static void
m0_op_sub_n( M0_CallFrame *frame, const unsigned char *ops )
{
- float *r2 = (float*) &(frame->registers[ops[2]]);
- float *r3 = (float*) &(frame->registers[ops[3]]);
- float *result = (float*) &(frame->registers[ops[1]]);
- frame->registers[ops[1]] = (uint64_t)0;
- *result = *r2 - *r3;
+ double r2 = *(double*)&frame->registers[ops[2]];
+ double r3 = *(double*)&frame->registers[ops[3]];
+ double *result = (double*) &(frame->registers[ops[1]]);
+ *result = r2 - r3;
}
static void
m0_op_convert_n_i( M0_CallFrame *frame, const unsigned char *ops )
{
int64_t *r2 = (int64_t*) &(frame->registers[ops[2]]);
- float *r1 = (float*) &(frame->registers[ops[1]]);
- frame->registers[ops[1]] = (uint64_t)0;
+ double *r1 = (double*) &(frame->registers[ops[1]]);
*r1 = (*r2);
}
static void
m0_op_convert_i_n( M0_CallFrame *frame, const unsigned char *ops )
{
- float *r2 = (float*) &(frame->registers[ops[2]]);
+ double *r2 = (double*) &(frame->registers[ops[2]]);
int64_t *r1 = (int64_t*) &(frame->registers[ops[1]]);
*r1 = *r2;
}
@@ -151,52 +124,55 @@ m0_op_goto_if( M0_CallFrame *frame, const unsigned char *ops )
static void
m0_op_mult_i( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = frame->registers[ops[2]] *
- frame->registers[ops[3]];
+ unsigned int r2 = *(unsigned int*)&frame->registers[ops[2]];
+ unsigned int r3 = *(unsigned int*)&frame->registers[ops[3]];
+ unsigned int *result = (unsigned int*) &(frame->registers[ops[1]]);
+ *result = r2 * r3;
}
static void
m0_op_mult_n( M0_CallFrame *frame, const unsigned char *ops )
{
- float *r2 = (float*) &(frame->registers[ops[2]]);
- float *r3 = (float*) &(frame->registers[ops[3]]);
- float *result = (float*) &(frame->registers[ops[1]]);
- frame->registers[ops[1]] = (uint64_t)0;
- *result = *r2 * *r3;
+ double r2 = *(double*)&frame->registers[ops[2]];
+ double r3 = *(double*)&frame->registers[ops[3]];
+ double *result = (double*) &(frame->registers[ops[1]]);
+ *result = r2 * r3;
}
static void
m0_op_div_i( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = frame->registers[ops[2]] /
- frame->registers[ops[3]];
+ unsigned int r2 = *(unsigned int*)&frame->registers[ops[2]];
+ unsigned int r3 = *(unsigned int*)&frame->registers[ops[3]];
+ unsigned int *result = (unsigned int*) &(frame->registers[ops[1]]);
+ *result = r2 / r3;
}
static void
m0_op_div_n( M0_CallFrame *frame, const unsigned char *ops )
{
- float *r2 = (float*) &(frame->registers[ops[2]]);
- float *r3 = (float*) &(frame->registers[ops[3]]);
- float *result = (float*) &(frame->registers[ops[1]]);
- frame->registers[ops[1]] = (uint64_t)0;
- *result = *r2 / *r3;
+ double r2 = *(double*)&frame->registers[ops[2]];
+ double r3 = *(double*)&frame->registers[ops[3]];
+ double *result = (double*) &(frame->registers[ops[1]]);
+ *result = r2 / r3;
}
static void
m0_op_mod_i( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = frame->registers[ops[2]] %
- frame->registers[ops[3]];
+ unsigned int r2 = *(unsigned int*)&frame->registers[ops[2]];
+ unsigned int r3 = *(unsigned int*)&frame->registers[ops[3]];
+ unsigned int *result = (unsigned int*) &(frame->registers[ops[1]]);
+ *result = r2 % r3;
}
static void
m0_op_mod_n( M0_CallFrame *frame, const unsigned char *ops )
{
- float *r2 = (float*) &(frame->registers[ops[2]]);
- float *r3 = (float*) &(frame->registers[ops[3]]);
- float *result = (float*) &(frame->registers[ops[1]]);
- frame->registers[ops[1]] = (uint64_t)0;
- *result = (int)(*r2) % (int)(*r3);
+ double r2 = *(double*)&frame->registers[ops[2]];
+ double r3 = *(double*)&frame->registers[ops[3]];
+ double *result = (double*) &(frame->registers[ops[1]]);
+ *result = (int)(r2) % (int)(r3);
}
static void
@@ -17,11 +17,14 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 4
deref N1, CONSTS, N1
+ deref N1, N1, 0
add_n N2, N1, N0
set_imm N3, 0, 5
deref N3, CONSTS, N3
+ deref N3, N3, 0
sub_n N4, N3, N2
goto_if addn_nok, N4
@@ -21,6 +21,7 @@
# N1 = 99.0 (from constants segment)
set_imm N1, 0, 3
deref N1, CONSTS, N1
+ deref N1, N1, 0
# N2 = 99 (from convert_i_n)
convert_i_n I2, N1, x
@@ -47,6 +48,7 @@ convert_i_n_ok1:
# N1 = -23.0 (from constants segment)
set_imm N1, 0, 4
deref N1, CONSTS, N1
+ deref N1, N1, 0
# N2 = -23 (from convert_i_n)
convert_i_n I2, N1, x
@@ -15,6 +15,7 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 99
sub_i N0, N0, N1
@@ -17,11 +17,14 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 4
deref N1, CONSTS, N1
+ deref N1, N1, 0
div_n N2, N0, N1
set_imm N3, 0, 5
deref N3, CONSTS, N3
+ deref N3, N3, 0
sub_n N4, N3, N2
goto_if divn_nok, N4
@@ -138,6 +138,7 @@ hash_loop_end:
# store known-good hash in I1
set_imm I1, 0, 4
deref I1, CONSTS, I1
+ deref I1, I1, 0
sub_i I1, I1, I4
@@ -17,11 +17,14 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 4
deref N1, CONSTS, N1
+ deref N1, N1, 0
mod_n N2, N0, N1
set_imm N3, 0, 5
deref N3, CONSTS, N3
+ deref N3, N3, 0
sub_n N4, N3, N2
goto_if modn_nok, N4
@@ -17,11 +17,14 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 4
deref N1, CONSTS, N1
+ deref N1, N1, 0
mult_n N2, N1, N0
set_imm N3, 0, 5
deref N3, CONSTS, N3
+ deref N3, N3, 0
sub_n N4, N3, N2
goto_if multn_nok, N4
@@ -45,6 +45,7 @@
# check that I23 == 9999
set_imm I1, 0, 8
deref I1, CONSTS, I1
+ deref I1, I1, 0
sub_i I1, I1, I23
goto_if preinvoke_nok, I1
@@ -15,6 +15,7 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set N1, N0, x
set_imm N0, 0, 99
sub_i N0, N0, N1
@@ -15,6 +15,7 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 99
sub_i N0, N0, N1
@@ -16,9 +16,11 @@
set_imm N0, 0, 4
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 4
deref N1, CONSTS, N1
+ deref N1, N1, 0
sub_i N0, N0, N1
goto_if set_ref_nok, N0
@@ -17,11 +17,14 @@
set_imm N0, 0, 3
deref N0, CONSTS, N0
+ deref N0, N0, 0
set_imm N1, 0, 4
deref N1, CONSTS, N1
+ deref N1, N1, 0
sub_n N2, N0, N1
set_imm N3, 0, 5
deref N3, CONSTS, N3
+ deref N3, N3, 0
sub_n N4, N3, N2
goto_if subn_nok, N4

0 comments on commit 48a8cc2

Please sign in to comment.