Added HuC6280 cpu (will be treated as a 65C02)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3612 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -406,17 +406,12 @@ unsigned OptJumpCascades (CodeSeg* S)
|
|||||||
/* Remember, we had changes */
|
/* Remember, we had changes */
|
||||||
++Changes;
|
++Changes;
|
||||||
|
|
||||||
/* Done */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if both are conditional branches, and the condition of
|
/* Check if both are conditional branches, and the condition of
|
||||||
* the second is the inverse of that of the first. In this case,
|
* the second is the inverse of that of the first. In this case,
|
||||||
* the second branch will never be taken, and we may jump directly
|
* the second branch will never be taken, and we may jump directly
|
||||||
* to the instruction behind this one.
|
* to the instruction behind this one.
|
||||||
*/
|
*/
|
||||||
if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) {
|
} else if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) {
|
||||||
|
|
||||||
CodeEntry* X; /* Instruction behind N */
|
CodeEntry* X; /* Instruction behind N */
|
||||||
CodeLabel* LX; /* Label attached to X */
|
CodeLabel* LX; /* Label attached to X */
|
||||||
@@ -448,9 +443,6 @@ unsigned OptJumpCascades (CodeSeg* S)
|
|||||||
/* Remember, we had changes */
|
/* Remember, we had changes */
|
||||||
++Changes;
|
++Changes;
|
||||||
|
|
||||||
/* Done */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
102
src/cc65/expr.c
102
src/cc65/expr.c
@@ -729,7 +729,9 @@ static void Primary (ExprDesc* E)
|
|||||||
strcpy (Ident, CurTok.Ident);
|
strcpy (Ident, CurTok.Ident);
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* IDENT is either an auto-declared function or an undefined variable. */
|
/* The identifier is either an implicitly declared function or an
|
||||||
|
* undefined variable.
|
||||||
|
*/
|
||||||
if (CurTok.Tok == TOK_LPAREN) {
|
if (CurTok.Tok == TOK_LPAREN) {
|
||||||
/* Declare a function returning int. For that purpose, prepare a
|
/* Declare a function returning int. For that purpose, prepare a
|
||||||
* function signature for a function having an empty param list
|
* function signature for a function having an empty param list
|
||||||
@@ -1827,7 +1829,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||||||
|
|
||||||
|
|
||||||
static void hie9 (ExprDesc* Expr)
|
static void hie9 (ExprDesc* Expr)
|
||||||
/* Process * and / operators. */
|
/* Process *, / and % */
|
||||||
{
|
{
|
||||||
static const GenDesc hie9_ops[] = {
|
static const GenDesc hie9_ops[] = {
|
||||||
{ TOK_STAR, GEN_NOPUSH, g_mul },
|
{ TOK_STAR, GEN_NOPUSH, g_mul },
|
||||||
@@ -1838,6 +1840,102 @@ static void hie9 (ExprDesc *Expr)
|
|||||||
int UsedGen;
|
int UsedGen;
|
||||||
|
|
||||||
hie_internal (hie9_ops, Expr, hie10, &UsedGen);
|
hie_internal (hie9_ops, Expr, hie10, &UsedGen);
|
||||||
|
|
||||||
|
|
||||||
|
ExprDesc Expr2;
|
||||||
|
CodeMark Mark1;
|
||||||
|
CodeMark Mark2;
|
||||||
|
const GenDesc* Gen;
|
||||||
|
token_t Tok; /* The operator token */
|
||||||
|
unsigned ltype, type;
|
||||||
|
int rconst; /* Operand is a constant */
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the left hand side */
|
||||||
|
ExprWithCheck (hie10, Expr);
|
||||||
|
|
||||||
|
/* Check if one of our operators follows */
|
||||||
|
while (CurTok.Tok == TOK_STAR ||
|
||||||
|
CurTok.Tok == TOK_DIV ||
|
||||||
|
CurTok.Tok == TOK_MOD) {
|
||||||
|
|
||||||
|
/* All operators that call this function expect an int on the lhs */
|
||||||
|
if (!IsClassInt (Expr->Type)) {
|
||||||
|
Error ("Integer expression expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember the operator token, then skip it */
|
||||||
|
Tok = CurTok.Tok;
|
||||||
|
NextToken ();
|
||||||
|
|
||||||
|
/* Get the lhs on stack */
|
||||||
|
GetCodePos (&Mark1);
|
||||||
|
ltype = TypeOf (Expr->Type);
|
||||||
|
if (ED_IsConstAbs (Expr)) {
|
||||||
|
/* Constant value */
|
||||||
|
GetCodePos (&Mark2);
|
||||||
|
g_push (ltype | CF_CONST, Expr->IVal);
|
||||||
|
} else {
|
||||||
|
/* Value not constant */
|
||||||
|
LoadExpr (CF_NONE, Expr);
|
||||||
|
GetCodePos (&Mark2);
|
||||||
|
g_push (ltype, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the right hand side */
|
||||||
|
rconst = (evalexpr (CF_NONE, hienext, &Expr2) == 0);
|
||||||
|
|
||||||
|
/* Check the type of the rhs */
|
||||||
|
if (!IsClassInt (Expr2.Type)) {
|
||||||
|
Error ("Integer expression expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for const operands */
|
||||||
|
if (ED_IsConstAbs (Expr) && rconst) {
|
||||||
|
|
||||||
|
/* Both operands are constant, remove the generated code */
|
||||||
|
RemoveCode (&Mark1);
|
||||||
|
|
||||||
|
/* Evaluate the result */
|
||||||
|
Expr->IVal = kcalc (Tok, Expr->IVal, Expr2.IVal);
|
||||||
|
|
||||||
|
/* Get the type of the result */
|
||||||
|
Expr->Type = promoteint (Expr->Type, Expr2.Type);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* If the right hand side is constant, and the generator function
|
||||||
|
* expects the lhs in the primary, remove the push of the primary
|
||||||
|
* now.
|
||||||
|
*/
|
||||||
|
unsigned rtype = TypeOf (Expr2.Type);
|
||||||
|
type = 0;
|
||||||
|
if (rconst) {
|
||||||
|
/* Second value is constant - check for div */
|
||||||
|
type |= CF_CONST;
|
||||||
|
rtype |= CF_CONST;
|
||||||
|
if (Tok == TOK_DIV && Expr2.IVal == 0) {
|
||||||
|
Error ("Division by zero");
|
||||||
|
} else if (Tok == TOK_MOD && Expr2.IVal == 0) {
|
||||||
|
Error ("Modulo operation with zero");
|
||||||
|
}
|
||||||
|
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
||||||
|
RemoveCode (&Mark2);
|
||||||
|
ltype |= CF_REG; /* Value is in register */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the type of the operation result. */
|
||||||
|
type |= g_typeadjust (ltype, rtype);
|
||||||
|
Expr->Type = promoteint (Expr->Type, Expr2.Type);
|
||||||
|
|
||||||
|
/* Generate code */
|
||||||
|
Gen->Func (type, Expr2.IVal);
|
||||||
|
|
||||||
|
/* We have a rvalue in the primary now */
|
||||||
|
ED_MakeRValExpr (Expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ static void OptCPU (const char* Opt, const char* Arg)
|
|||||||
/* Find the CPU from the given name */
|
/* Find the CPU from the given name */
|
||||||
CPU = FindCPU (Arg);
|
CPU = FindCPU (Arg);
|
||||||
if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 &&
|
if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 &&
|
||||||
CPU != CPU_65C02 && CPU != CPU_65816) {
|
CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280) {
|
||||||
AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
|
AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user