implement float
This commit is contained in:
parent
d09d712f1b
commit
b266c6b4d3
129
c/execute.c
129
c/execute.c
@ -315,7 +315,9 @@ void op_f2d(struct vm * vm)
|
|||||||
|
|
||||||
void op_f2i(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)
|
void op_f2l(struct vm * vm)
|
||||||
@ -325,122 +327,189 @@ void op_f2l(struct vm * vm)
|
|||||||
|
|
||||||
void op_fadd(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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
void op_i2l(struct vm * vm)
|
||||||
@ -873,8 +944,8 @@ void op_ior(struct vm * vm)
|
|||||||
|
|
||||||
void op_irem(struct vm * vm)
|
void op_irem(struct vm * vm)
|
||||||
{
|
{
|
||||||
uint32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||||
uint32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||||
int32_t result = value1 % value2;
|
int32_t result = value1 % value2;
|
||||||
operand_stack_push_u32(vm->current_frame, result);
|
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];
|
struct constant * constant = &vm->current_thread.current_class->constant_pool[index - 1];
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
assert(constant->tag == CONSTANT_Integer);
|
assert(constant->tag == CONSTANT_Integer || constant->tag == CONSTANT_Float);
|
||||||
#endif
|
#endif
|
||||||
int32_t value = constant->integer.bytes;
|
int32_t value = constant->integer.bytes;
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
|
@ -141,6 +141,7 @@ void vm_method_return(struct vm * vm)
|
|||||||
vm->current_frame->pc = vm->current_frame->next_pc;
|
vm->current_frame->pc = vm->current_frame->next_pc;
|
||||||
|
|
||||||
switch (old_frame->return_type) {
|
switch (old_frame->return_type) {
|
||||||
|
case 'F': [[fallthrough]];
|
||||||
case 'I':
|
case 'I':
|
||||||
uint32_t value = operand_stack_pop_u32(old_frame);
|
uint32_t value = operand_stack_pop_u32(old_frame);
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
@ -163,7 +164,7 @@ static void print_vm_stack(struct vm * vm)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int32_t value = vm->current_frame->operand_stack[vm->current_frame->operand_stack_ix - i];
|
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);
|
printf("0x%08x ", value);
|
||||||
else
|
else
|
||||||
printf("%10d ", value);
|
printf("%10d ", value);
|
||||||
@ -174,12 +175,12 @@ static void print_vm_stack(struct vm * vm)
|
|||||||
void vm_execute(struct vm * vm)
|
void vm_execute(struct vm * vm)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
|
assert(vm->current_frame->pc < vm->current_frame->code->code_length);
|
||||||
print_vm_stack(vm);
|
print_vm_stack(vm);
|
||||||
decode_print_instruction(vm->current_frame->code->code, vm->current_frame->pc);
|
decode_print_instruction(vm->current_frame->code->code, vm->current_frame->pc);
|
||||||
uint32_t old_pc = vm->current_frame->pc;
|
uint32_t old_pc = vm->current_frame->pc;
|
||||||
struct method_info * old_method = vm->current_thread.current_method;
|
struct method_info * old_method = vm->current_thread.current_method;
|
||||||
decode_execute_instruction(vm, vm->current_frame->code->code, vm->current_frame->pc);
|
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) {
|
if (vm->frame_stack.ix == 1) {
|
||||||
printf("terminate\n");
|
printf("terminate\n");
|
||||||
break;
|
break;
|
||||||
|
16
c/frame.h
16
c/frame.h
@ -60,5 +60,21 @@ static inline void operand_stack_dup_u32(struct frame * frame)
|
|||||||
frame->operand_stack_ix++;
|
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_static_method_call(struct vm * vm, struct class_file * class_file, struct method_info * method_info);
|
||||||
void vm_method_return(struct vm * vm);
|
void vm_method_return(struct vm * vm);
|
||||||
|
32
p/Float.java
Normal file
32
p/Float.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user