+int CE_IsKnownImm (const CodeEntry* E, unsigned long Num)
+/* Return true if the argument of E is a constant immediate value that is
+ * equal to Num.
+ */
+{
+ return E->AM == AM65_IMM &&
+ (E->Flags & CEF_NUMARG) != 0 &&
+ E->Num == Num;
+}
+
+
+
+int CE_UseLoadFlags (const CodeEntry* E)
+/* Return true if the instruction uses any flags that are set by a load of
+ * a register (N and Z).
+ */
+{
+ /* Follow unconditional branches, but beware of endless loops. After this,
+ * E will point to the first entry that is not a branch.
+ */
+ if (E->Info & OF_UBRA) {
+ Collection C = AUTO_COLLECTION_INITIALIZER;
+
+ /* Follow the chain */
+ while (E->Info & OF_UBRA) {
+
+ /* Remember the entry so we can detect loops */
+ CollAppend (&C, (void*) E);
+
+ /* Check the target */
+ if (E->JumpTo == 0 || CollIndex (&C, E->JumpTo->Owner) >= 0) {
+ /* Unconditional jump to external symbol, or endless loop. */
+ DoneCollection (&C);
+ return 0; /* Flags not used */
+ }
+
+ /* Follow the chain */
+ E = E->JumpTo->Owner;
+ }
+
+ /* Delete the collection */
+ DoneCollection (&C);
+ }
+
+ /* A branch will use the flags */
+ if (E->Info & OF_FBRA) {
+ return 1;
+ }
+
+ /* Call of a boolean transformer routine will also use the flags */
+ if (E->OPC == OP65_JSR) {
+ /* Get the condition that is evaluated and check it */
+ switch (FindBoolCmpCond (E->Arg)) {
+ case CMP_EQ:
+ case CMP_NE:
+ case CMP_GT:
+ case CMP_GE:
+ case CMP_LT:
+ case CMP_LE:
+ case CMP_UGT:
+ case CMP_ULE:
+ /* Will use the N or Z flags */
+ return 1;
+
+
+ case CMP_UGE: /* Uses only carry */
+ case CMP_ULT: /* Dito */
+ default: /* No bool transformer subroutine */
+ return 0;
+ }
+ }
+
+ /* Anything else */
+ return 0;
+}
+
+
+