+static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
+/* Set the Use and Chg in E */
+{
+ /* If this is a subroutine call, or a jump to an external function,
+ * lookup the information about this function and use it. The jump itself
+ * does not change any registers, so we don't need to use the data from D.
+ */
+ if (E->OPC == OPC_JSR || ((E->Info & OF_BRA) != 0 && E->JumpTo == 0)) {
+ /* A subroutine call or jump to external symbol (function exit) */
+ GetFuncInfo (E->Arg, &E->Use, &E->Chg);
+ } else {
+ /* Some other instruction. Use the values from the opcode description
+ * plus addressing mode info
+ */
+ E->Use = D->Use | GetAMUseInfo (E->AM);
+ E->Chg = D->Chg;
+ }
+}
+
+
+
/*****************************************************************************/
/* Code */
/*****************************************************************************/
/* Get the opcode description */
const OPCDesc* D = GetOPCDesc (OPC);
- /* Allocate memory */
+ /* Allocate memory */
CodeEntry* E = xmalloc (sizeof (CodeEntry));
/* Initialize the fields */
E->Hints = 0;
E->Arg = GetArgCopy (Arg);
if (NumArg (E->Arg, &E->Num)) {
- E-> Flags = CEF_NUMARG;
+ E-> Flags = CEF_NUMARG;
} else {
E->Flags = 0;
}
- E->Info = D->Info;
- E->Use = D->Use;
- E->Chg = D->Chg;
- if (E->OPC == OPC_JSR) {
- /* A subroutine call */
- GetFuncInfo (E->Arg, &E->Use, &E->Chg);
- } else if ((E->Info & OF_BRA) != 0 && JumpTo == 0) {
- /* Jump to external symbol (function exit) */
- GetFuncInfo (E->Arg, &E->Use, &E->Chg);
- } else {
- /* Some other instruction */
- E->Use |= GetAMUseInfo (E->AM);
- }
+ E->Info = D->Info;
E->JumpTo = JumpTo;
+ SetUseChgInfo (E, D);
InitCollection (&E->Labels);
/* If we have a label given, add this entry to the label */
const OPCDesc* D = GetOPCDesc (OPC);
/* Replace the opcode */
- E->OPC = OPC;
- E->Size = GetInsnSize (E->OPC, E->AM);
- E->Info = D->Info;
- E->Use = D->Use;
- E->Chg = D->Chg;
- if (E->OPC == OPC_JSR) {
- /* A subroutine call */
- GetFuncInfo (E->Arg, &E->Use, &E->Chg);
- } else {
- /* Some other instruction */
- E->Use |= GetAMUseInfo (E->AM);
- }
+ E->OPC = OPC;
+ E->Size = GetInsnSize (E->OPC, E->AM);
+ E->Info = D->Info;
+ SetUseChgInfo (E, D);
}
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
-/* For the given function, lookup register information and combine it with
- * the information already in place. If the function is unknown, assume it
- * will use all registers and load all registers.
- * See codeinfo.h for possible flags.
+/* For the given function, lookup register information and store it into
+ * the given variables. If the function is unknown, assume it will use and
+ * load all registers.
*/
{
/* Search for the function */
const FuncInfo* Info = bsearch (Name, FuncInfoTable, FuncInfoCount,
- sizeof(FuncInfo), CompareFuncInfo);
+ sizeof(FuncInfo), CompareFuncInfo);
/* Do we know the function? */
if (Info) {
/* Use the information we have */
- *Use |= Info->Use;
- *Chg |= Info->Chg;
+ *Use = Info->Use;
+ *Chg = Info->Chg;
} else {
/* Assume all registers used */
- *Use |= REG_AXY;
- *Chg |= REG_AXY;
+ *Use = REG_AXY;
+ *Chg = REG_AXY;
}
}
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg);
-/* For the given function, lookup register information and combine it with
- * the information already in place. If the function is unknown, assume it
- * will use all registers and load all registers.
+/* For the given function, lookup register information and store it into
+ * the given variables. If the function is unknown, assume it will use and
+ * load all registers.
*/
unsigned char GetRegInfo (struct CodeSeg* S, unsigned Index);
*/
{
unsigned Changes = 0;
- unsigned I;
-
- /* Get the number of entries, bail out if we have no entries */
- unsigned Count = GetCodeEntryCount (S);
- if (Count == 0) {
- return 0;
- }
/* Walk over all entries */
- I = 0;
- while (I < Count) {
+ unsigned I = 0;
+ while (I < GetCodeEntryCount (S)) {
+
+ CodeEntry* N;
+ CodeLabel* OldLabel;
/* Get this entry */
CodeEntry* E = GetCodeEntry (S, I);
- /* Check if it's a branch, if it has a jump label, and if this jump
- * label is not attached to the instruction itself.
+ /* Check if it's a branch, if it has a jump label, if this jump
+ * label is not attached to the instruction itself, and if the
+ * target instruction is itself a branch.
*/
- if ((E->Info & OF_BRA) != 0 && E->JumpTo != 0 && E->JumpTo->Owner != E) {
-
- /* Get the label this insn is branching to */
- CodeLabel* OldLabel = E->JumpTo;
-
- /* Get the entry we're branching to */
- CodeEntry* N = OldLabel->Owner;
-
- /* If the entry we're branching to is not itself a branch, it is
- * not what we're searching for.
- */
- if ((N->Info & OF_BRA) == 0) {
- goto NextEntry;
- }
+ if ((E->Info & OF_BRA) != 0 &&
+ (OldLabel = E->JumpTo) != 0 &&
+ (N = OldLabel->Owner) != E &&
+ (N->Info & OF_BRA) != 0) {
/* Check if we can use the final target label. This is the case,
* if the target branch is an absolut branch, or if it is a
GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) {
/* This is a jump cascade and we may jump to the final target.
- * If we have a label, move the reference to this label. If
- * we don't have a label, use the argument instead.
+ * Insert a new instruction, then remove the old one
*/
- if (N->JumpTo) {
- /* Move the reference to the new insn */
- MoveCodeLabelRef (S, E, N->JumpTo);
- } else {
- /* Remove the reference to the old label */
- RemoveCodeLabelRef (S, E);
- }
+ CodeEntry* X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo);
- /* Use the new argument */
- CodeEntrySetArg (E, N->Arg);
+ /* Insert it behind E */
+ InsertCodeEntry (S, X, I+1);
- /* Use the usage information from the new instruction */
- E->Use = N->Use;
- E->Chg = N->Chg;
+ /* Remove E */
+ DelCodeEntry (S, I);
/* Remember, we had changes */
++Changes;
*/
if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) {
- unsigned NI; /* Index of N */
CodeEntry* X; /* Instruction behind N */
CodeLabel* LX; /* Label attached to X */
goto NextEntry;
}
- /* We may jump behind this conditional branch. This means that
- * N may not be the last entry.
+ /* We may jump behind this conditional branch. Get the
+ * pointer to the next instruction
*/
- NI = GetCodeEntryIndex (S, N);
- if (NI >= Count-1) {
- /* N is last entry */
+ if ((X = GetNextCodeEntry (S, GetCodeEntryIndex (S, N))) == 0) {
+ /* N is the last entry, bail out */
goto NextEntry;
}
- /* Get the pointer to the next instruction */
- X = GetCodeEntry (S, NI+1);
-
/* Get the label attached to X, create a new one if needed */
LX = GenCodeLabel (S, X);