Permalink
Browse files

Merge pull request #753 from nbrown/m0-c-new-ops

M0 c new ops
  • Loading branch information...
2 parents 5246f7c + 86b55be commit e21d417823b9b220e2a820179e7fb67bf268bf18 @leto leto committed Apr 2, 2012
Showing with 123 additions and 3 deletions.
  1. +11 −0 src/m0/c/include/m0_interp_structures.h
  2. +112 −3 src/m0/c/m0_ops.c
@@ -32,5 +32,16 @@ enum CF_NAMED_REGS {
SPILLCF
};
+typedef enum {
+ INVALID,
+ NAMED,
+ INTEGER,
+ NUMBER,
+ STRING,
+ POINTER
+} M0_RegisterType;
+
+
+
# define M0_INTERP_STRUCTURES_H 1
#endif
View
@@ -11,6 +11,21 @@ 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 )
{
@@ -28,8 +43,25 @@ 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)consts->consts[ offset ];
+ 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);
break;
}
default:
@@ -78,6 +110,16 @@ m0_op_add_n( M0_CallFrame *frame, const unsigned char *ops )
}
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;
+}
+
+static void
m0_op_sub_i( M0_CallFrame *frame, const unsigned char *ops )
{
const uint64_t result = *(uint64_t *) frame->registers[ops[2]] +
@@ -96,15 +138,30 @@ m0_op_sub_n( M0_CallFrame *frame, const unsigned char *ops )
}
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;
+}
+
+static void
m0_op_convert_n_i( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = (double)(frame->registers[ops[2]]);
+ int64_t *r2 = (int64_t*) &(frame->registers[ops[2]]);
+ float *r1 = (float*) &(frame->registers[ops[1]]);
+ frame->registers[ops[1]] = (uint64_t)0;
+ *r1 = (*r2);
}
static void
m0_op_convert_i_n( M0_CallFrame *frame, const unsigned char *ops )
{
- frame->registers[ops[1]] = (int)(frame->registers[ops[2]]);
+ float *r2 = (float*) &(frame->registers[ops[2]]);
+ int64_t *r1 = (int64_t*) &(frame->registers[ops[1]]);
+ *r1 = *r2;
}
static void
@@ -128,20 +185,50 @@ m0_op_mult_i( M0_CallFrame *frame, const unsigned char *ops )
}
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;
+}
+
+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]];
}
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;
+}
+
+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]];
}
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);
+}
+
+static void
m0_op_and( M0_CallFrame *frame, const unsigned char *ops )
{
frame->registers[ops[1]] = frame->registers[ops[2]] &
@@ -220,6 +307,12 @@ m0_op_set_byte( M0_CallFrame *frame, const unsigned char *ops )
}
static void
+m0_op_set( M0_CallFrame *frame, const unsigned char *ops )
+{
+ frame->registers[ops[1]] = frame->registers[ops[2]];
+}
+
+static void
m0_op_get_byte( M0_CallFrame *frame, const unsigned char *ops )
{
const char *src = (char*)frame->registers[ops[3]];
@@ -299,14 +392,26 @@ run_ops( M0_Interp *interp, M0_CallFrame *cf ) {
m0_op_mult_i( cf, &ops[pc] );
break;
+ case (M0_MULT_N):
+ m0_op_mult_n( cf, &ops[pc] );
+ break;
+
case (M0_DIV_I):
m0_op_div_i( cf, &ops[pc] );
break;
+ case (M0_DIV_N):
+ m0_op_div_n( cf, &ops[pc] );
+ break;
+
case (M0_MOD_I):
m0_op_mod_i( cf, &ops[pc] );
break;
+ case (M0_MOD_N):
+ m0_op_mod_n( cf, &ops[pc] );
+ break;
+
case (M0_AND):
m0_op_and( cf, &ops[pc] );
break;
@@ -339,6 +444,10 @@ run_ops( M0_Interp *interp, M0_CallFrame *cf ) {
m0_op_set_byte( cf, &ops[pc] );
break;
+ case (M0_SET):
+ m0_op_set( cf, &ops[pc] );
+ break;
+
case (M0_GET_BYTE):
m0_op_get_byte( cf, &ops[pc] );
break;

0 comments on commit e21d417

Please sign in to comment.