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)
|
||||
{
|
||||
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);
|
||||
|
@ -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;
|
||||
|
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++;
|
||||
}
|
||||
|
||||
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
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