/* */
/* */
/* */
-/* (C) 1998-2006 Ullrich von Bassewitz */
-/* Römerstraße 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 1998-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
int IsFarRange (long Val);
/* Return true if this is a far (24 bit) value */
+int IsEasyConst (const ExprNode* E, long* Val);
+/* Do some light checking if the given node is a constant. Don't care if E is
+ * a complex expression. If E is a constant, return true and place its value
+ * into Val, provided that Val is not NULL.
+ */
+
ExprNode* CloneExpr (ExprNode* Expr);
/* Clone the given expression tree. The function will simply clone symbol
* nodes, it will not resolve them.
/* */
/* */
/* */
-/* (C) 1998-2008 Ullrich von Bassewitz */
-/* Roemerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 1998-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* Emit an instruction with a zero sized operand */
{
Fragment* F = GenFragment (FRAG_LITERAL, 1);
- F->V.Data [0] = OPC;
+ F->V.Data[0] = OPC;
}
void Emit1 (unsigned char OPC, ExprNode* Value)
/* Emit an instruction with an one byte argument */
{
- Emit0 (OPC);
- EmitByte (Value);
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Value, &V)) {
+
+ /* Must be in byte range */
+ if (!IsByteRange (V)) {
+ Error ("Range error (%ld not in [0..255])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 2);
+ F->V.Data[0] = OPC;
+ F->V.Data[1] = (unsigned char) V;
+ FreeExpr (Value);
+
+ } else {
+
+ /* Emit the opcode */
+ Emit0 (OPC);
+
+ /* Emit the argument as an expression */
+ F = GenFragment (FRAG_EXPR, 1);
+ F->V.Expr = Value;
+ }
}
void Emit2 (unsigned char OPC, ExprNode* Value)
/* Emit an instruction with a two byte argument */
{
- Emit0 (OPC);
- EmitWord (Value);
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Value, &V)) {
+
+ /* Must be in byte range */
+ if (!IsWordRange (V)) {
+ Error ("Range error (%ld not in [0..65535])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 3);
+ F->V.Data[0] = OPC;
+ F->V.Data[1] = (unsigned char) V;
+ F->V.Data[2] = (unsigned char) (V >> 8);
+ FreeExpr (Value);
+
+ } else {
+
+ /* Emit the opcode */
+ Emit0 (OPC);
+
+ /* Emit the argument as an expression */
+ F = GenFragment (FRAG_EXPR, 2);
+ F->V.Expr = Value;
+ }
}
void EmitByte (ExprNode* Expr)
/* Emit one byte */
{
- /* Create a new fragment */
- Fragment* F = GenFragment (FRAG_EXPR, 1);
-
- /* Set the data */
- F->V.Expr = Expr;
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Expr, &V)) {
+ /* Must be in byte range */
+ if (!IsByteRange (V)) {
+ Error ("Range error (%ld not in [0..255])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 1);
+ F->V.Data[0] = (unsigned char) V;
+ FreeExpr (Expr);
+ } else {
+ /* Emit the argument as an expression */
+ F = GenFragment (FRAG_EXPR, 1);
+ F->V.Expr = Expr;
+ }
}
void EmitWord (ExprNode* Expr)
/* Emit one word */
{
- /* Create a new fragment */
- Fragment* F = GenFragment (FRAG_EXPR, 2);
-
- /* Set the data */
- F->V.Expr = Expr;
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Expr, &V)) {
+ /* Must be in byte range */
+ if (!IsWordRange (V)) {
+ Error ("Range error (%ld not in [0..65535])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 2);
+ F->V.Data[0] = (unsigned char) V;
+ F->V.Data[1] = (unsigned char) (V >> 8);
+ FreeExpr (Expr);
+ } else {
+ /* Emit the argument as an expression */
+ Fragment* F = GenFragment (FRAG_EXPR, 2);
+ F->V.Expr = Expr;
+ }
}