implement float

This commit is contained in:
Zack Buhman 2024-12-24 01:41:48 -06:00
parent d09d712f1b
commit b266c6b4d3
4 changed files with 151 additions and 31 deletions

View File

@ -315,7 +315,9 @@ void op_f2d(struct vm * vm)
void op_f2i(struct vm * vm)
{
assert(!"op_f2i");
float value = operand_stack_pop_f32(vm->current_frame);
int32_t result = (int32_t)value;
operand_stack_push_u32(vm->current_frame, result);
}
void op_f2l(struct vm * vm)
@ -325,122 +327,189 @@ void op_f2l(struct vm * vm)
void op_fadd(struct vm * vm)
{
assert(!"op_fadd");
float value2 = operand_stack_pop_f32(vm->current_frame);
float value1 = operand_stack_pop_f32(vm->current_frame);
float result = value1 + value2;
operand_stack_push_f32(vm->current_frame, result);
}
void op_faload(struct vm * vm)
{
assert(!"op_faload");
int32_t index = operand_stack_pop_u32(vm->current_frame);
int32_t * arrayref = (int32_t *)operand_stack_pop_u32(vm->current_frame);
assert(arrayref[0] > 0 && index < arrayref[0]);
int32_t * intarray = (int32_t *)&arrayref[1];
int32_t value = intarray[index];
operand_stack_push_u32(vm->current_frame, value);
}
void op_fastore(struct vm * vm)
{
assert(!"op_fastore");
int32_t value = operand_stack_pop_u32(vm->current_frame);
int32_t index = operand_stack_pop_u32(vm->current_frame);
int32_t * arrayref = (int32_t *)operand_stack_pop_u32(vm->current_frame);
assert(arrayref[0] > 0 && index < arrayref[0]);
int32_t * intarray = (int32_t *)&arrayref[1];
intarray[index] = value;
}
void op_fcmpg(struct vm * vm)
{
assert(!"op_fcmpg");
float value2 = operand_stack_pop_f32(vm->current_frame);
float value1 = operand_stack_pop_f32(vm->current_frame);
bool greater = value1 > value2;
bool equal = value1 == value2;
int32_t value;
if (__builtin_isnan(value1) || __builtin_isnan(value2)) {
value = 1;
} else if (equal) {
value = 0;
} else if (greater) {
value = 1;
} else { // less than
value = -1;
}
operand_stack_push_u32(vm->current_frame, value);
}
void op_fcmpl(struct vm * vm)
{
assert(!"op_fcmpl");
float value2 = operand_stack_pop_f32(vm->current_frame);
float value1 = operand_stack_pop_f32(vm->current_frame);
bool greater = value1 > value2;
bool equal = value1 == value2;
int32_t value;
if (__builtin_isnan(value1) || __builtin_isnan(value2)) {
value = -1;
} else if (equal) {
value = 0;
} else if (greater) {
value = 1;
} else { // less than
value = -1;
}
operand_stack_push_u32(vm->current_frame, value);
}
void op_fconst_0(struct vm * vm)
{
assert(!"op_fconst_0");
operand_stack_push_f32(vm->current_frame, 0.0f);
}
void op_fconst_1(struct vm * vm)
{
assert(!"op_fconst_1");
operand_stack_push_f32(vm->current_frame, 1.0f);
}
void op_fconst_2(struct vm * vm)
{
assert(!"op_fconst_2");
operand_stack_push_f32(vm->current_frame, 2.0f);
}
void op_fdiv(struct vm * vm)
{
assert(!"op_fdiv");
float value2 = operand_stack_pop_f32(vm->current_frame);
float value1 = operand_stack_pop_f32(vm->current_frame);
float result = value1 / value2;
operand_stack_push_f32(vm->current_frame, result);
}
void op_fload(struct vm * vm, uint32_t index)
{
assert(!"op_fload");
uint32_t value = vm->current_frame->local_variable[index];
operand_stack_push_u32(vm->current_frame, value);
}
void op_fload_0(struct vm * vm)
{
assert(!"op_fload_0");
uint32_t value = vm->current_frame->local_variable[0];
operand_stack_push_u32(vm->current_frame, value);
}
void op_fload_1(struct vm * vm)
{
assert(!"op_fload_1");
uint32_t value = vm->current_frame->local_variable[1];
operand_stack_push_u32(vm->current_frame, value);
}
void op_fload_2(struct vm * vm)
{
assert(!"op_fload_2");
uint32_t value = vm->current_frame->local_variable[2];
operand_stack_push_u32(vm->current_frame, value);
}
void op_fload_3(struct vm * vm)
{
assert(!"op_fload_3");
uint32_t value = vm->current_frame->local_variable[3];
operand_stack_push_u32(vm->current_frame, value);
}
void op_fmul(struct vm * vm)
{
assert(!"op_fmul");
float value2 = operand_stack_pop_f32(vm->current_frame);
float value1 = operand_stack_pop_f32(vm->current_frame);
float result = value1 * value2;
operand_stack_push_f32(vm->current_frame, result);
}
void op_fneg(struct vm * vm)
{
assert(!"op_fneg");
float value = operand_stack_pop_f32(vm->current_frame);
float result = -value;
operand_stack_push_f32(vm->current_frame, result);
}
void op_frem(struct vm * vm)
{
assert(!"op_frem");
float value2 = operand_stack_pop_f32(vm->current_frame);
float value1 = operand_stack_pop_f32(vm->current_frame);
float q = value1 / value2;
float result = value1 - (value2 * (float)((int32_t)q));
operand_stack_push_f32(vm->current_frame, result);
}
void op_freturn(struct vm * vm)
{
assert(!"op_freturn");
assert(vm->current_frame->return_type == 'F');
vm_method_return(vm);
}
void op_fstore(struct vm * vm, uint32_t index)
{
assert(!"op_fstore");
uint32_t value = operand_stack_pop_u32(vm->current_frame);
vm->current_frame->local_variable[index] = value;
}
void op_fstore_0(struct vm * vm)
{
assert(!"op_fstore_0");
uint32_t value = operand_stack_pop_u32(vm->current_frame);
vm->current_frame->local_variable[0] = value;
}
void op_fstore_1(struct vm * vm)
{
assert(!"op_fstore_1");
uint32_t value = operand_stack_pop_u32(vm->current_frame);
vm->current_frame->local_variable[1] = value;
}
void op_fstore_2(struct vm * vm)
{
assert(!"op_fstore_2");
uint32_t value = operand_stack_pop_u32(vm->current_frame);
vm->current_frame->local_variable[2] = value;
}
void op_fstore_3(struct vm * vm)
{
assert(!"op_fstore_3");
uint32_t value = operand_stack_pop_u32(vm->current_frame);
vm->current_frame->local_variable[3] = value;
}
void op_fsub(struct vm * vm)
{
assert(!"op_fsub");
float value2 = operand_stack_pop_f32(vm->current_frame);
float value1 = operand_stack_pop_f32(vm->current_frame);
float result = value1 - value2;
operand_stack_push_f32(vm->current_frame, result);
}
void op_getfield(struct vm * vm, uint32_t index)
@ -517,7 +586,9 @@ void op_i2d(struct vm * vm)
void op_i2f(struct vm * vm)
{
assert(!"op_i2f");
int32_t value = operand_stack_pop_u32(vm->current_frame);
float result = (float)value;
operand_stack_push_f32(vm->current_frame, result);
}
void op_i2l(struct vm * vm)
@ -873,8 +944,8 @@ void op_ior(struct vm * vm)
void op_irem(struct vm * vm)
{
uint32_t value2 = operand_stack_pop_u32(vm->current_frame);
uint32_t value1 = operand_stack_pop_u32(vm->current_frame);
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
int32_t result = value1 % value2;
operand_stack_push_u32(vm->current_frame, result);
}
@ -1039,7 +1110,7 @@ void op_ldc(struct vm * vm, uint32_t index)
{
struct constant * constant = &vm->current_thread.current_class->constant_pool[index - 1];
#ifdef DEBUG
assert(constant->tag == CONSTANT_Integer);
assert(constant->tag == CONSTANT_Integer || constant->tag == CONSTANT_Float);
#endif
int32_t value = constant->integer.bytes;
operand_stack_push_u32(vm->current_frame, value);

View File

@ -141,6 +141,7 @@ void vm_method_return(struct vm * vm)
vm->current_frame->pc = vm->current_frame->next_pc;
switch (old_frame->return_type) {
case 'F': [[fallthrough]];
case 'I':
uint32_t value = operand_stack_pop_u32(old_frame);
operand_stack_push_u32(vm->current_frame, value);
@ -163,7 +164,7 @@ static void print_vm_stack(struct vm * vm)
continue;
}
int32_t value = vm->current_frame->operand_stack[vm->current_frame->operand_stack_ix - i];
if (value > 65536)
if (value > 32767 || value < -32768)
printf("0x%08x ", value);
else
printf("%10d ", value);
@ -174,12 +175,12 @@ static void print_vm_stack(struct vm * vm)
void vm_execute(struct vm * vm)
{
while (true) {
assert(vm->current_frame->pc < vm->current_frame->code->code_length);
print_vm_stack(vm);
decode_print_instruction(vm->current_frame->code->code, vm->current_frame->pc);
uint32_t old_pc = vm->current_frame->pc;
struct method_info * old_method = vm->current_thread.current_method;
decode_execute_instruction(vm, vm->current_frame->code->code, vm->current_frame->pc);
//if (vm->current_frame->pc >= vm->current_frame->code->code_length) {
if (vm->frame_stack.ix == 1) {
printf("terminate\n");
break;

View File

@ -60,5 +60,21 @@ static inline void operand_stack_dup_u32(struct frame * frame)
frame->operand_stack_ix++;
}
static inline void operand_stack_push_f32(struct frame * frame, float f)
{
uint32_t value = *((uint32_t *)&f);
frame->operand_stack[frame->operand_stack_ix] = value;
frame->operand_stack_ix++;
}
static inline float operand_stack_pop_f32(struct frame * frame)
{
frame->operand_stack_ix--;
uint32_t value = frame->operand_stack[frame->operand_stack_ix];
frame->operand_stack[frame->operand_stack_ix] = -1;
float f = *((float *)&value);
return f;
}
void vm_static_method_call(struct vm * vm, struct class_file * class_file, struct method_info * method_info);
void vm_method_return(struct vm * vm);

32
p/Float.java Normal file
View File

@ -0,0 +1,32 @@
package p;
class Float {
public static void main() {
test2();
}
static float test() {
float a = 1.0f;
float b = a / 3.0f;
float c = b * 2.0f;
float d = c + 5.0f;
float e = d - 0.5f;
float f = -e;
float g = f % 2.0f;
int h = (int)g;
return h;
}
static float test2() {
float[] arr = {1.0f, 2.1f, 3.2f, 4.3f};
float sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
boolean b = sum < 1.0f;
float i = 0.0f;
if (b)
i = 1.0f;
return i * 4.2f;
}
}