#ifndef __GRAVITY_IRCODE__
#define __GRAVITY_IRCODE__
#include "debug_macros.h"
#include "gravity_opcodes.h"
#include "gravity_array.h"
#define IRCODE_LATEST UINT32_MAX
typedef enum {
NO_TAG = 0,
INT_TAG,
DOUBLE_TAG,
LABEL_TAG,
SKIP_TAG,
RANGE_INCLUDE_TAG,
RANGE_EXCLUDE_TAG,
PRAGMA_OPTIMIZATION
} optag_t;
typedef struct {
opcode_t op;
optag_t tag;
int32_t p1;
int32_t p2;
int32_t p3;
union {
double d;
int64_t n;
};
} inst_t;
typedef struct ircode_t ircode_t;
ircode_t *ircode_create (uint16_t nlocals);
void ircode_free (ircode_t *code);
uint32_t ircode_count (ircode_t *code);
uint32_t ircode_ntemps (ircode_t *code);
inst_t *ircode_get (ircode_t *code, uint32_t index);
void ircode_dump (void *code);
void ircode_push_context (ircode_t *code);
void ircode_pop_context (ircode_t *code);
bool ircode_iserror (ircode_t *code);
void ircode_patch_init (ircode_t *code, uint16_t index);
uint32_t ircode_newlabel (ircode_t *code);
void ircode_setlabel_true (ircode_t *code, uint32_t nlabel);
void ircode_setlabel_false (ircode_t *code, uint32_t nlabel);
void ircode_unsetlabel_true (ircode_t *code);
void ircode_unsetlabel_false (ircode_t *code);
uint32_t ircode_getlabel_true (ircode_t *code);
uint32_t ircode_getlabel_false (ircode_t *code);
void ircode_marklabel (ircode_t *code, uint32_t nlabel);
void inst_setskip (inst_t *inst);
uint8_t opcode_numop (opcode_t op);
void ircode_add (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3);
void ircode_add_tag (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag);
void ircode_add_array (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, uint32_r r);
void ircode_add_double (ircode_t *code, double d);
void ircode_add_int (ircode_t *code, int64_t n);
void ircode_add_constant (ircode_t *code, uint32_t index);
void ircode_add_skip (ircode_t *code);
void ircode_set_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3);
void ircode_setarray_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, uint32_r r);
bool ircode_register_istemp (ircode_t *code, uint32_t n);
uint32_t ircode_register_push_temp (ircode_t *code);
uint32_t ircode_register_push (ircode_t *code, uint32_t nreg);
uint32_t ircode_register_pop (ircode_t *code);
uint32_t ircode_register_pop_protect (ircode_t *code, bool protect);
void ircode_register_protect (ircode_t *code, uint32_t nreg);
uint32_t ircode_register_last (ircode_t *code);
uint32_t ircode_register_count (ircode_t *code);
void ircode_register_clean (ircode_t *code, uint32_t nreg);
void ircode_register_dump (ircode_t *code);
#endif