From 09359235c724fa0b25e0e5085f0f26c245e44739 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Sat, 18 Jan 2020 00:07:26 +0100 Subject: [PATCH] Add immediate addressing mode for short branches and BRK to support some ugly tricks --- docs/lang/assembly.md | 3 +++ .../scala/millfork/assembly/mos/opt/CoarseFlowAnalyzer.scala | 4 ++++ .../scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala | 2 ++ src/main/scala/millfork/output/MosAssembler.scala | 1 + 4 files changed, 10 insertions(+) diff --git a/docs/lang/assembly.md b/docs/lang/assembly.md index de82c6d9..0a273ade 100644 --- a/docs/lang/assembly.md +++ b/docs/lang/assembly.md @@ -13,6 +13,9 @@ There are two ways to include raw assembly code in your Millfork programs: Millfork inline assembly uses the same three-letter opcodes as most other 6502 assemblers. Indexing syntax is also the same. Only instructions available on the current CPU architecture are available. +The short branching instructions and the `BRK` instruction support the immediate addressing mode, +for more control over code generation. + The `BBRn/BBSn/SMBn/RMBn` instructions cannot parameterize the tested bit. The syntax is as follows: BBR1 $10,label diff --git a/src/main/scala/millfork/assembly/mos/opt/CoarseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/mos/opt/CoarseFlowAnalyzer.scala index d6771f5c..99c7c615 100644 --- a/src/main/scala/millfork/assembly/mos/opt/CoarseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/mos/opt/CoarseFlowAnalyzer.scala @@ -136,6 +136,10 @@ object CoarseFlowAnalyzer { case AssemblyLine0(op, Implied, _) if FlowAnalyzerForImplied.hasDefinition(op) => currentStatus = FlowAnalyzerForImplied.get(op)(currentStatus) + case AssemblyLine0(op, Immediate, _) if OpcodeClasses.ShortBranching(op) => + // don't even both optimizing functions with weird jumps, it's futile + return cache.put(code, List.fill[CpuStatus](code.length)(initialStatus)) + case AssemblyLine0(op, Immediate | WordImmediate, NumericConstant(nn, _)) if FlowAnalyzerForImmediate.hasDefinition(op) => currentStatus = FlowAnalyzerForImmediate.get(op)(nn.toInt, currentStatus) diff --git a/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala index e3b9e3bb..f1eb7a2e 100644 --- a/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala @@ -172,6 +172,8 @@ object ReverseFlowAnalyzer { case _ => false } currentImportance = if (labelIndex < 0) finalImportance else importanceArray(labelIndex) ~ currentImportance + case AssemblyLine0(opcode, Immediate, _) if OpcodeClasses.ShortConditionalBranching(opcode) => + currentImportance = finalImportance case AssemblyLine0(opcode, ZeroPageWithRelative, StructureConstant(_, List(_, MemoryAddressConstant(Label(l))))) if OpcodeClasses.SingleBitBranch(opcode) => val L = l val labelIndex = codeArray.indexWhere { diff --git a/src/main/scala/millfork/output/MosAssembler.scala b/src/main/scala/millfork/output/MosAssembler.scala index 85657a83..0538ebff 100644 --- a/src/main/scala/millfork/output/MosAssembler.scala +++ b/src/main/scala/millfork/output/MosAssembler.scala @@ -397,6 +397,7 @@ object MosAssembler { op(BEQ, Relative, 0xF0) op(BRK, Implied, 0) + op(BRK, Immediate, 0) op(CMP, Immediate, 0xC9) op(CMP, ZeroPage, 0xC5)