implement double
This commit is contained in:
parent
eef2c848e8
commit
d0edd6b12b
157
c/execute.c
157
c/execute.c
@ -149,132 +149,225 @@ void op_checkcast(struct vm * vm, uint32_t index)
|
|||||||
|
|
||||||
void op_d2f(struct vm * vm)
|
void op_d2f(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_d2f");
|
double value = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
float result = (float)value;
|
||||||
|
operand_stack_push_f32(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_d2i(struct vm * vm)
|
void op_d2i(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_d2i");
|
double value = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
int32_t result = (int32_t)value;
|
||||||
|
operand_stack_push_u32(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_d2l(struct vm * vm)
|
void op_d2l(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_d2l");
|
double value = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
int64_t result = (int64_t)value;
|
||||||
|
operand_stack_push_u64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dadd(struct vm * vm)
|
void op_dadd(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dadd");
|
double value2 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double value1 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double result = value1 + value2;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_daload(struct vm * vm)
|
void op_daload(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_daload");
|
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]);
|
||||||
|
int64_t * longarray = (int64_t *)&arrayref[1];
|
||||||
|
int64_t value = longarray[index];
|
||||||
|
operand_stack_push_u64(vm->current_frame, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dastore(struct vm * vm)
|
void op_dastore(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dastore");
|
int64_t value = operand_stack_pop_u64(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]);
|
||||||
|
int64_t * longarray = (int64_t *)&arrayref[1];
|
||||||
|
longarray[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dcmpg(struct vm * vm)
|
void op_dcmpg(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dcmpg");
|
double value2 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double value1 = operand_stack_pop_f64(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_dcmpl(struct vm * vm)
|
void op_dcmpl(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dcmpl");
|
double value2 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double value1 = operand_stack_pop_f64(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_dconst_0(struct vm * vm)
|
void op_dconst_0(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dconst_0");
|
operand_stack_push_f64(vm->current_frame, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dconst_1(struct vm * vm)
|
void op_dconst_1(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dconst_1");
|
operand_stack_push_f64(vm->current_frame, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_ddiv(struct vm * vm)
|
void op_ddiv(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_ddiv");
|
double value2 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double value1 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double result = value1 / value2;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dload(struct vm * vm, uint32_t index)
|
void op_dload(struct vm * vm, uint32_t index)
|
||||||
{
|
{
|
||||||
assert(!"op_dload");
|
uint32_t low = vm->current_frame->local_variable[index];
|
||||||
|
uint32_t high = vm->current_frame->local_variable[index + 1];
|
||||||
|
operand_stack_push_u32(vm->current_frame, low);
|
||||||
|
operand_stack_push_u32(vm->current_frame, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dload_0(struct vm * vm)
|
void op_dload_0(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dload_0");
|
uint32_t low = vm->current_frame->local_variable[0];
|
||||||
|
uint32_t high = vm->current_frame->local_variable[0 + 1];
|
||||||
|
operand_stack_push_u32(vm->current_frame, low);
|
||||||
|
operand_stack_push_u32(vm->current_frame, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dload_1(struct vm * vm)
|
void op_dload_1(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dload_1");
|
uint32_t low = vm->current_frame->local_variable[1];
|
||||||
|
uint32_t high = vm->current_frame->local_variable[1 + 1];
|
||||||
|
operand_stack_push_u32(vm->current_frame, low);
|
||||||
|
operand_stack_push_u32(vm->current_frame, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dload_2(struct vm * vm)
|
void op_dload_2(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dload_2");
|
uint32_t low = vm->current_frame->local_variable[2];
|
||||||
|
uint32_t high = vm->current_frame->local_variable[2 + 1];
|
||||||
|
operand_stack_push_u32(vm->current_frame, low);
|
||||||
|
operand_stack_push_u32(vm->current_frame, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dload_3(struct vm * vm)
|
void op_dload_3(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dload_3");
|
uint32_t low = vm->current_frame->local_variable[3];
|
||||||
|
uint32_t high = vm->current_frame->local_variable[3 + 1];
|
||||||
|
operand_stack_push_u32(vm->current_frame, low);
|
||||||
|
operand_stack_push_u32(vm->current_frame, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dmul(struct vm * vm)
|
void op_dmul(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dmul");
|
double value2 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double value1 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double result = value1 * value2;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dneg(struct vm * vm)
|
void op_dneg(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dneg");
|
double value = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double result = -value;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_drem(struct vm * vm)
|
void op_drem(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_drem");
|
double value2 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double value1 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double q = value1 / value2;
|
||||||
|
double result = value1 - (value2 * (double)((int64_t)q));
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dreturn(struct vm * vm)
|
void op_dreturn(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dreturn");
|
assert(vm->current_frame->return_type == 'D');
|
||||||
|
vm_method_return(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dstore(struct vm * vm, uint32_t index)
|
void op_dstore(struct vm * vm, uint32_t index)
|
||||||
{
|
{
|
||||||
assert(!"op_dstore");
|
uint32_t high = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
uint32_t low = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
vm->current_frame->local_variable[index + 1] = high;
|
||||||
|
vm->current_frame->local_variable[index] = low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dstore_0(struct vm * vm)
|
void op_dstore_0(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dstore_0");
|
uint32_t high = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
uint32_t low = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
vm->current_frame->local_variable[0 + 1] = high;
|
||||||
|
vm->current_frame->local_variable[0] = low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dstore_1(struct vm * vm)
|
void op_dstore_1(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dstore_1");
|
uint32_t high = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
uint32_t low = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
vm->current_frame->local_variable[1 + 1] = high;
|
||||||
|
vm->current_frame->local_variable[1] = low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dstore_2(struct vm * vm)
|
void op_dstore_2(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dstore_2");
|
uint32_t high = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
uint32_t low = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
vm->current_frame->local_variable[2 + 1] = high;
|
||||||
|
vm->current_frame->local_variable[2] = low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dstore_3(struct vm * vm)
|
void op_dstore_3(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dstore_3");
|
uint32_t high = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
uint32_t low = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
vm->current_frame->local_variable[3 + 1] = high;
|
||||||
|
vm->current_frame->local_variable[3] = low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dsub(struct vm * vm)
|
void op_dsub(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_dsub");
|
double value2 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double value1 = operand_stack_pop_f64(vm->current_frame);
|
||||||
|
double result = value1 - value2;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_dup(struct vm * vm)
|
void op_dup(struct vm * vm)
|
||||||
@ -309,7 +402,9 @@ void op_dup_x2(struct vm * vm)
|
|||||||
|
|
||||||
void op_f2d(struct vm * vm)
|
void op_f2d(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_f2d");
|
float value = operand_stack_pop_f32(vm->current_frame);
|
||||||
|
double result = (double)value;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_f2i(struct vm * vm)
|
void op_f2i(struct vm * vm)
|
||||||
@ -589,7 +684,9 @@ void op_i2c(struct vm * vm)
|
|||||||
|
|
||||||
void op_i2d(struct vm * vm)
|
void op_i2d(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_i2d");
|
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
double result = (double)value;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_i2f(struct vm * vm)
|
void op_i2f(struct vm * vm)
|
||||||
@ -1092,7 +1189,9 @@ void op_jsr_w(struct vm * vm, int32_t branch)
|
|||||||
|
|
||||||
void op_l2d(struct vm * vm)
|
void op_l2d(struct vm * vm)
|
||||||
{
|
{
|
||||||
assert(!"op_l2d");
|
int64_t value = operand_stack_pop_u64(vm->current_frame);
|
||||||
|
double result = (double)value;
|
||||||
|
operand_stack_push_f64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_l2f(struct vm * vm)
|
void op_l2f(struct vm * vm)
|
||||||
|
20
c/frame.h
20
c/frame.h
@ -127,6 +127,26 @@ static inline uint64_t operand_stack_pop_u64(struct frame * frame)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void operand_stack_push_f64(struct frame * frame, double f)
|
||||||
|
{
|
||||||
|
uint64_t value = *((uint64_t *)&f);
|
||||||
|
frame->operand_stack[frame->operand_stack_ix] = (uint32_t)(value >> 0);
|
||||||
|
frame->operand_stack_ix++;
|
||||||
|
frame->operand_stack[frame->operand_stack_ix] = (uint32_t)(value >> 32);
|
||||||
|
frame->operand_stack_ix++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double operand_stack_pop_f64(struct frame * frame)
|
||||||
|
{
|
||||||
|
frame->operand_stack_ix--;
|
||||||
|
uint64_t high = frame->operand_stack[frame->operand_stack_ix];
|
||||||
|
frame->operand_stack_ix--;
|
||||||
|
uint64_t low = frame->operand_stack[frame->operand_stack_ix];
|
||||||
|
uint64_t value = (high << 32) | (low << 0);
|
||||||
|
double f = *((double *)&value);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
bool vm_initialize_class(struct vm * vm, struct class_entry * class_entry);
|
bool vm_initialize_class(struct vm * vm, struct class_entry * class_entry);
|
||||||
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);
|
||||||
|
48
p/Double.java
Normal file
48
p/Double.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package p;
|
||||||
|
|
||||||
|
class Double {
|
||||||
|
public static void main() {
|
||||||
|
test();
|
||||||
|
test2();
|
||||||
|
test3(3.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double test() {
|
||||||
|
double a = 1.0;
|
||||||
|
double b = a / 3.0;
|
||||||
|
double c = b * 2.0;
|
||||||
|
double d = c + 5.0;
|
||||||
|
double e = d - 0.5;
|
||||||
|
double f = -e;
|
||||||
|
double g = f % 2.0;
|
||||||
|
int h = (int)g;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double test2() {
|
||||||
|
double[] arr = {1.0, 2.1, 3.2, 4.3};
|
||||||
|
double sum = 0;
|
||||||
|
for (int i = 0; i < arr.length; i++) {
|
||||||
|
sum += arr[i];
|
||||||
|
}
|
||||||
|
boolean b = sum < 1.0;
|
||||||
|
double i = 0.0;
|
||||||
|
if (b)
|
||||||
|
i = 1.0;
|
||||||
|
return i * 4.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double test3(double n) {
|
||||||
|
float a = (float)n;
|
||||||
|
int b = (int)n;
|
||||||
|
long c = (long)n;
|
||||||
|
char d = (char)n;
|
||||||
|
|
||||||
|
double e = (double)a;
|
||||||
|
double f = (double)b;
|
||||||
|
double g = (double)c;
|
||||||
|
double h = (double)d;
|
||||||
|
|
||||||
|
return e * f * g * h;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user