written to a data file called "profile-raw". */
/* #define VM_PROFILING (1) */
+/* Comment this definition to turn off floating-point support. You
+ might need to do this if you are building on a very limited platform
+ with no math library. */
+#define FLOAT_SUPPORT (1)
+
/* Some macros to read and write integers to memory, always in big-endian
format. */
#define Read4(ptr) \
#if VERIFY_MEMORY_ACCESS
#define Verify(adr, ln) verify_address(adr, ln)
+#define VerifyW(adr, ln) verify_address_write(adr, ln)
#else
#define Verify(adr, ln) (0)
+#define VerifyW(adr, ln) (0)
#endif /* VERIFY_MEMORY_ACCESS */
#define Mem1(adr) (Verify(adr, 1), Read1(memmap+(adr)))
#define Mem2(adr) (Verify(adr, 2), Read2(memmap+(adr)))
#define Mem4(adr) (Verify(adr, 4), Read4(memmap+(adr)))
-#define MemW1(adr, vl) (Verify(adr, 1), Write1(memmap+(adr), (vl)))
-#define MemW2(adr, vl) (Verify(adr, 2), Write2(memmap+(adr), (vl)))
-#define MemW4(adr, vl) (Verify(adr, 4), Write4(memmap+(adr), (vl)))
+#define MemW1(adr, vl) (VerifyW(adr, 1), Write1(memmap+(adr), (vl)))
+#define MemW2(adr, vl) (VerifyW(adr, 2), Write2(memmap+(adr), (vl)))
+#define MemW4(adr, vl) (VerifyW(adr, 4), Write4(memmap+(adr), (vl)))
/* Macros to access values on the stack. These *must* be used
with proper alignment! (That is, Stk4 and StkW4 must take
/* Some useful structures. */
-/* instruction_t:
- Represents the list of operands to an instruction being executed.
- (Yes, it's somewhat misnamed. Sorry.) We assume, for the indefinite
- moment, that no opcode has more than 8 operands, and no opcode
- has two "store" operands.
+/* oparg_t:
+ Represents one operand value to an instruction being executed. The
+ code in exec.c assumes that no instruction has more than MAX_OPERANDS
+ of these.
*/
-typedef struct instruction_struct {
+typedef struct oparg_struct {
glui32 desttype;
- glui32 value[8];
-} instruction_t;
+ glui32 value;
+} oparg_t;
+
+#define MAX_OPERANDS (8)
/* operandlist_t:
Represents the operand structure of an opcode.
extern glui32 change_memsize(glui32 newlen, int internal);
extern glui32 *pop_arguments(glui32 count, glui32 addr);
extern void verify_address(glui32 addr, glui32 count);
+extern void verify_address_write(glui32 addr, glui32 count);
+extern void verify_array_addresses(glui32 addr, glui32 count, glui32 size);
/* exec.c */
extern void execute_loop(void);
extern operandlist_t *fast_operandlist[0x80];
extern void init_operands(void);
extern operandlist_t *lookup_operandlist(glui32 opcode);
-extern void parse_operands(instruction_t *inst, operandlist_t *oplist);
+extern void parse_operands(oparg_t *opargs, operandlist_t *oplist);
extern void store_operand(glui32 desttype, glui32 destaddr, glui32 storeval);
extern void store_operand_s(glui32 desttype, glui32 destaddr, glui32 storeval);
extern void store_operand_b(glui32 desttype, glui32 destaddr, glui32 storeval);
extern strid_t find_stream_by_id(glui32 objid);
/* profile.c */
+extern void setup_profile(strid_t stream, char *filename);
extern int init_profile(void);
#if VM_PROFILING
extern glui32 profile_opcount;
#define profile_tick() (profile_opcount++)
-extern void profile_in(glui32 addr, int accel);
-extern void profile_out(void);
+extern void profile_in(glui32 addr, glui32 stackuse, int accel);
+extern void profile_out(glui32 stackuse);
extern void profile_fail(char *reason);
extern void profile_quit(void);
#else /* VM_PROFILING */
-#define profile_tick() (0)
-#define profile_in(addr, accel) (0)
-#define profile_out() (0)
-#define profile_fail(reason) (0)
-#define profile_quit() (0)
+#define profile_tick() (0)
+#define profile_in(addr, stackuse, accel) (0)
+#define profile_out(stackuse) (0)
+#define profile_fail(reason) (0)
+#define profile_quit() (0)
#endif /* VM_PROFILING */
/* accel.c */
extern void accel_set_func(glui32 index, glui32 addr);
extern void accel_set_param(glui32 index, glui32 val);
+#ifdef FLOAT_SUPPORT
+
+/* You may have to edit the definition of gfloat32 to make sure it's really
+ a 32-bit floating-point type. */
+typedef float gfloat32;
+
+/* Uncomment this definition if your gfloat32 type is not a standard
+ IEEE-754 single-precision (32-bit) format. Normally, Glulxe assumes
+ that it can reinterpret-cast IEEE-754 int values into gfloat32
+ values. If you uncomment this, Glulxe switches to lengthier
+ (but safer) encoding and decoding functions. */
+/* #define FLOAT_NOT_NATIVE (1) */
+
+/* float.c */
+extern int init_float(void);
+extern glui32 encode_float(gfloat32 val);
+extern gfloat32 decode_float(glui32 val);
+
+/* Uncomment this definition if your powf() function does not support
+ all the corner cases specified by C99. If you uncomment this,
+ osdepend.c will provide a safer implementation of glulx_powf(). */
+/* #define FLOAT_COMPILE_SAFER_POWF (1) */
+
+extern gfloat32 glulx_powf(gfloat32 val1, gfloat32 val2);
+
+#endif /* FLOAT_SUPPORT */
+
#endif /* _GLULXE_H */