Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ISSOtm committed Apr 19, 2021
1 parent 6d0a3c7 commit c53890d
Show file tree
Hide file tree
Showing 6 changed files with 388 additions and 499 deletions.
67 changes: 22 additions & 45 deletions include/asm/rpn.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,52 +17,29 @@
#define MAXRPNLEN 1048576

struct Expression {
int32_t val; // If the expression's value is known, it's here
char *reason; // Why the expression is not known, if it isn't
bool isKnown; // Whether the expression's value is known
bool isSymbol; // Whether the expression represents a symbol
uint8_t *rpn; // Array of bytes serializing the RPN expression
uint32_t rpnCapacity; // Size of the `tRPN` buffer
uint32_t rpnLength; // Used size of the `tRPN` buffer
uint32_t rpnPatchSize; // Size the expression will take in the obj file
size_t rpnLength; // Used size of the `rpn` buffer
uint32_t rpnPatchSize; // Size the expression will take in the object file
uint8_t rpn[]; // Array of bytes serializing the RPN expression
};

/*
* Determines if an expression is known at assembly time
*/
static inline bool rpn_isKnown(const struct Expression *expr)
{
return expr->isKnown;
}

/*
* Determines if an expression is a symbol suitable for const diffing
*/
static inline bool rpn_isSymbol(const struct Expression *expr)
{
return expr->isSymbol;
}

void rpn_Symbol(struct Expression *expr, char const *symName);
void rpn_Number(struct Expression *expr, uint32_t i);
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
struct Symbol const *rpn_SymbolOf(struct Expression const *expr);
bool rpn_IsDiffConstant(struct Expression const *src, struct Symbol const *symName);
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
const struct Expression *src1,
const struct Expression *src2);
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
void rpn_LOW(struct Expression *expr, const struct Expression *src);
void rpn_ISCONST(struct Expression *expr, const struct Expression *src);
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
void rpn_BankSymbol(struct Expression *expr, char const *symName);
void rpn_BankSection(struct Expression *expr, char const *sectionName);
void rpn_BankSelf(struct Expression *expr);
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName);
void rpn_StartOfSection(struct Expression *expr, char const *sectionName);
void rpn_Free(struct Expression *expr);
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
// Terminals (literals)
struct Expression *rpn_BankSymbol(char const *symName);
struct Expression *rpn_BankSection(char const *sectionName);
struct Expression *rpn_BankSelf(void);
struct Expression *rpn_SizeOfSection(char const *sectionName);
struct Expression *rpn_StartOfSection(char const *sectionName);
struct Expression *rpn_Number(uint32_t i);
struct Expression *rpn_Symbol(char const *symName);
// Unary operators
struct Expression *rpn_HIGH(struct Expression *expr); // Thin wrapper, never emitted in object files
struct Expression *rpn_LOW(struct Expression *expr); // Thin wrapper, never emitted in object files
struct Expression *rpn_ISCONST(struct Expression *expr); // Never emitted in object files, constant
struct Expression *rpn_NEG(struct Expression *expr);
struct Expression *rpn_NOT(struct Expression *expr);
struct Expression *rpn_LOGNOT(struct Expression *expr);
struct Expression *rpn_CheckHRAM(struct Expression *expr);
struct Expression *rpn_CheckRST(struct Expression *expr);
// Binary operators
struct Expression *rpn_BinaryOp(struct Expression *lhs, enum RPNCommand op, struct Expression *rhs);

#endif /* RGBDS_ASM_RPN_H */
19 changes: 19 additions & 0 deletions include/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#ifndef HELPERS_H
#define HELPERS_H

#include <stdint.h>

#include "platform.h"

// Of course, MSVC does not support C11, so no _Noreturn there...
#ifdef _MSC_VER
#define _Noreturn __declspec(noreturn)
Expand Down Expand Up @@ -88,4 +92,19 @@
#define STR(x) #x
#define EXPAND_AND_STR(x) STR(x)

// Helper function to write a LE 32-bit value to a buffer

static inline uint32_t readLE32(uint8_t ptr[MIN_NB_ELMS(4)])
{
return ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24;
}

static inline void writeLE32(uint8_t ptr[MIN_NB_ELMS(4)], uint32_t i)
{
ptr[0] = i;
ptr[1] = i >> 8;
ptr[2] = i >> 16;
ptr[3] = i >> 24;
}

#endif /* HELPERS_H */
7 changes: 4 additions & 3 deletions include/linkdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ enum RPNCommand {
RPN_MUL = 0x02,
RPN_DIV = 0x03,
RPN_MOD = 0x04,
RPN_UNSUB = 0x05,
RPN_UNSUB = 0x05, // FIXME: should be renamed to "NEG" for consistency
RPN_EXP = 0x06,

RPN_OR = 0x10,
RPN_AND = 0x11,
RPN_XOR = 0x12,
RPN_UNNOT = 0x13,
RPN_UNNOT = 0x13, // FIXME: should be renamed to "NOT" for consistency

RPN_LOGAND = 0x21,
RPN_LOGOR = 0x22,
RPN_LOGUNNOT = 0x23,
RPN_LOGUNNOT = 0x23, // FIXME: should be renamed to "LOGNOT" for consistency

RPN_LOGEQ = 0x30,
RPN_LOGNE = 0x31,
Expand All @@ -49,6 +49,7 @@ enum RPNCommand {

RPN_SHL = 0x40,
RPN_SHR = 0x41,
RPN_ISCONST = 0x42, // This is supposed to stay internal to RGBASM

RPN_BANK_SYM = 0x50,
RPN_BANK_SECT = 0x51,
Expand Down
2 changes: 1 addition & 1 deletion src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ enum {
{
char symName[MAXSYMLEN + 1];
char string[MAXSTRLEN + 1];
struct Expression expr;
struct Expression *expr;
int32_t constValue;
enum SectionModifier sectMod;
struct SectionSpec sectSpec;
Expand Down
7 changes: 4 additions & 3 deletions src/asm/rgbasm.5
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,13 @@ equivalent to multiplying and dividing by 2 to the power of b, respectively.
.Pp
Comparison operators return 0 if the comparison is false, and 1 otherwise.
.Pp
Unlike in a lot of languages, and for technical reasons,
Like in a lot of languages,
.Nm
still evaluates both operands of
only evaluates the left operand of
.Sq &&
and
.Sq || .
.Sq ||
if it's equal to 0 or 1 respectively.
.Pp
.Ic \&!
returns 1 if the operand was 0, and 0 otherwise.
Expand Down
Loading

0 comments on commit c53890d

Please sign in to comment.