jvm/c/decode.c
2024-12-27 07:11:22 -06:00

202 lines
6.9 KiB
C

#include <stdint.h>
#include "assert.h"
#include "decode.h"
#include "execute.h"
#include "bswap.h"
#include "printf.h"
static inline uint32_t _u4(const uint8_t * buf)
{
uint32_t n =
buf[0] << 24
| buf[1] << 16
| buf[2] << 8
| buf[3] << 0
;
return n;
}
static inline uint32_t _u2(const uint8_t * buf)
{
uint32_t n =
buf[0] << 8
| buf[1] << 0
;
return n;
}
static inline uint32_t _u1(const uint8_t * buf)
{
uint32_t n = buf[0];
return n;
}
static inline int32_t _s4(const uint8_t * buf)
{
int32_t n =
buf[0] << 24
| buf[1] << 16
| buf[2] << 8
| buf[3] << 0
;
return n;
}
static inline int32_t _s2(const uint8_t * buf)
{
int16_t n =
buf[0] << 8
| buf[1] << 0
;
return n;
}
static inline int32_t _s1(const uint8_t * buf)
{
int8_t n = buf[0];
return n;
}
static inline int32_t aligned_s4(const void * buf)
{
uint32_t n = *((uint32_t *)buf);
return BE_BSWAP32(n);
}
#define TABLESWITCH_ARGS \
uint32_t args = ((pc + 1) + 3) & (~3); \
int32_t defaultbyte = aligned_s4(&code[args + 0]); \
int32_t lowbyte = aligned_s4(&code[args + 4]); \
int32_t highbyte = aligned_s4(&code[args + 8]); \
const int32_t * table = (const int32_t *)&code[args + 12];
#define TABLESWITCH_PRINT_ARGS() \
do { \
for (int i = lowbyte; i <= highbyte; i++) { \
debugf(" %d: %d\n", i, aligned_s4(&table[i - lowbyte])); \
} \
debugf("default: %d\n", defaultbyte); \
} while (0);
#define TABLESWITCH_NEXT_PC \
(args + (3 * 4) + ((highbyte - lowbyte + 1) * 4))
#define LOOKUPSWITCH_ARGS \
uint32_t args = ((pc + 1) + 3) & (~3); \
int32_t defaultbyte = aligned_s4(&code[args + 0]); \
int32_t npairs = aligned_s4(&code[args + 4]); \
const int32_t * table = (const int32_t *)&code[args + 8];
#define LOOKUPSWITCH_PRINT_ARGS() \
do { \
for (int i = 0; i < npairs; i++) { \
debugf(" %d: %d\n", aligned_s4(&table[i * 2]), aligned_s4(&table[i * 2 + 1])); \
} \
debugf("default: %d\n", defaultbyte); \
} while (0);
#define LOOKUPSWITCH_NEXT_PC \
(args + (2 * 4) + (npairs * 2 * 4))
#define WIDE_ARGS \
uint32_t opcode = code[pc + 1]; \
uint32_t index = _u2(&code[pc + 2]); \
uint32_t wide_next_pc = pc + 4; \
int32_t _const; \
(void)_const;
#define WIDE_IMPL() \
switch (opcode) { \
case 21: /* iload */ \
op_iload(vm, index); \
break; \
case 22: /* lload */ \
op_lload(vm, index); \
break; \
case 23: /* fload */ \
op_fload(vm, index); \
break; \
case 24: /* dload */ \
op_dload(vm, index); \
break; \
case 25: /* aload */ \
op_aload(vm, index); \
break; \
case 54: /* istore */ \
op_istore(vm, index); \
break; \
case 56: /* fstore */ \
op_fstore(vm, index); \
break; \
case 58: /* astore */ \
op_astore(vm, index); \
break; \
case 55: /* lstore */ \
op_lstore(vm, index); \
break; \
case 57: /* dstore */ \
op_dstore(vm, index); \
break; \
case 169: /* ret */ \
op_ret(vm, index); \
break; \
case 132: /* iinc */ \
{ \
_const = _s2(&code[pc + 4]); \
op_iinc(vm, index, _const); \
wide_next_pc = pc + 6; \
} \
break; \
} \
vm->current_frame->next_pc = wide_next_pc;
#define WIDE_PRINT_ARGS() \
switch (opcode) { \
case 21: /* iload */ \
debugf(" iload %5d ", index); \
break; \
case 22: /* lload */ \
debugf(" lload %5d ", index); \
break; \
case 23: /* fload */ \
debugf(" fload %5d ", index); \
break; \
case 24: /* dload */ \
debugf(" dload %5d ", index); \
break; \
case 25: /* aload */ \
debugf(" aload %5d ", index); \
break; \
case 54: /* istore */ \
debugf(" istore %5d ", index); \
break; \
case 56: /* fstore */ \
debugf(" fstore %5d ", index); \
break; \
case 58: /* astore */ \
debugf(" astore %5d ", index); \
break; \
case 55: /* lstore */ \
debugf(" lstore %5d ", index); \
break; \
case 57: /* dstore */ \
debugf(" dstore %5d ", index); \
break; \
case 169: /* ret */ \
debugf(" ret %5d ", index); \
break; \
case 132: /* iinc */ \
_const = _s2(&code[pc + 4]); \
debugf(" iinc %5d %5d ", index, _const); \
wide_next_pc = pc + 6; \
break; \
}
#define WIDE_NEXT_PC wide_next_pc
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#include "decode.inc.c"
#pragma GCC diagnostic pop