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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
assert(!"op_dconst_0");
|
||||
operand_stack_push_f64(vm->current_frame, 0.0f);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
assert(!"op_dreturn");
|
||||
assert(vm->current_frame->return_type == 'D');
|
||||
vm_method_return(vm);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -309,7 +402,9 @@ void op_dup_x2(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)
|
||||
@ -589,7 +684,9 @@ void op_i2c(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)
|
||||
@ -1092,7 +1189,9 @@ void op_jsr_w(struct vm * vm, int32_t branch)
|
||||
|
||||
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)
|
||||
|
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
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