diff --git a/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java b/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java index 1997ab2..a62496c 100644 --- a/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java +++ b/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java @@ -1086,13 +1086,14 @@ public class M68kParser implements PsiParser, LightPsiParser { } /* ********************************************************** */ - // (DataRegister OP_MINUS DataRegister) | (AddressRegister OP_MINUS AddressRegister) + // (DataRegister OP_MINUS DataRegister) | (AddressRegister OP_MINUS AddressRegister) | (DataRegister OP_MINUS AddressRegister) public static boolean RegisterRange(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "RegisterRange")) return false; boolean r; Marker m = enter_section_(b, l, _NONE_, REGISTER_RANGE, ""); r = RegisterRange_0(b, l + 1); if (!r) r = RegisterRange_1(b, l + 1); + if (!r) r = RegisterRange_2(b, l + 1); exit_section_(b, l, m, r, false, null); return r; } @@ -1121,6 +1122,18 @@ public class M68kParser implements PsiParser, LightPsiParser { return r; } + // DataRegister OP_MINUS AddressRegister + private static boolean RegisterRange_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "RegisterRange_2")) return false; + boolean r; + Marker m = enter_section_(b); + r = DataRegister(b, l + 1); + r = r && consumeToken(b, OP_MINUS); + r = r && AddressRegister(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + /* ********************************************************** */ // REG_CCR | REG_SR | REG_USP | REG_VBR public static boolean SpecialRegister(PsiBuilder b, int l) { diff --git a/src/main/gen/de/platon42/intellij/plugins/m68k/psi/impl/M68kProgramCounterIndirectWithIndexOldAddressingModeImpl.java b/src/main/gen/de/platon42/intellij/plugins/m68k/psi/impl/M68kProgramCounterIndirectWithIndexOldAddressingModeImpl.java index c702783..a8ef085 100644 --- a/src/main/gen/de/platon42/intellij/plugins/m68k/psi/impl/M68kProgramCounterIndirectWithIndexOldAddressingModeImpl.java +++ b/src/main/gen/de/platon42/intellij/plugins/m68k/psi/impl/M68kProgramCounterIndirectWithIndexOldAddressingModeImpl.java @@ -42,4 +42,5 @@ public class M68kProgramCounterIndirectWithIndexOldAddressingModeImpl extends M6 public M68kDataWidth getIndexWidth() { return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class); } + } diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf b/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf index 4aeda9d..a79352b 100644 --- a/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf +++ b/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf @@ -351,7 +351,7 @@ ProgramCounterIndirectWithIndexNewAddressingMode ::= ROUND_L (expr SEPARATOR)? P AbsoluteAddressAddressingMode ::= expr AddressSize? !ROUND_L -RegisterRange ::= (DataRegister OP_MINUS DataRegister) | (AddressRegister OP_MINUS AddressRegister) { +RegisterRange ::= (DataRegister OP_MINUS DataRegister) | (AddressRegister OP_MINUS AddressRegister) | (DataRegister OP_MINUS AddressRegister) { name = "register range" methods = [ startRegister = "Register[0]" diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiImplUtil.kt b/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiImplUtil.kt index 65b7207..f08ea9c 100644 --- a/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiImplUtil.kt +++ b/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiImplUtil.kt @@ -123,8 +123,12 @@ object M68kPsiImplUtil { var startReg = Register.getRegFromName(it.startRegister.text) val endReg = Register.getRegFromName(it.endRegister!!.text) registers.add(startReg) - while (startReg.num < endReg.num) { - startReg = Register.getRegFromName(startReg.regname.dropLast(1) + (startReg.num + 1)) + while ((startReg.num < endReg.num) || (startReg.regname.dropLast(1) != endReg.regname.dropLast(1))) { + startReg = if (startReg.num < 7) { + Register.getRegFromName(startReg.regname.dropLast(1) + (startReg.num + 1)) + } else { + Register.A0 // handle wrap around from d7->a0 + } registers.add(startReg) } } diff --git a/src/test/java/de/platon42/intellij/plugins/m68k/parser/AddressingModesTest.kt b/src/test/java/de/platon42/intellij/plugins/m68k/parser/AddressingModesTest.kt index e0df813..9f907a0 100644 --- a/src/test/java/de/platon42/intellij/plugins/m68k/parser/AddressingModesTest.kt +++ b/src/test/java/de/platon42/intellij/plugins/m68k/parser/AddressingModesTest.kt @@ -98,6 +98,17 @@ internal class AddressingModesTest : AbstractParsingTest() { ) } + @Test + internal fun movem_register_list_with_data_address_wrapping(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) { + testGoodSyntax(testCase, " movem.l d0-a6,-(sp)\n") + val element = testCase.file.findElementAt(9) + val regList = PsiTreeUtil.getParentOfType(element, M68kRegisterListAddressingMode::class.java)!! + assertThat(regList.registers).containsExactlyInAnyOrder( + Register.D0, Register.D1, Register.D2, Register.D3, Register.D4, Register.D5, Register.D6, Register.D7, + Register.A0, Register.A1, Register.A2, Register.A3, Register.A4, Register.A5, Register.A6, + ) + } + @Test internal fun immediate_data(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) { testGoodSyntax(testCase, " moveq.l #FOO_BAR,d0\n") diff --git a/src/test/resources/parser/addressingmodes/movem_register_list_with_data_address_wrapping.txt b/src/test/resources/parser/addressingmodes/movem_register_list_with_data_address_wrapping.txt new file mode 100644 index 0000000..a51e69b --- /dev/null +++ b/src/test/resources/parser/addressingmodes/movem_register_list_with_data_address_wrapping.txt @@ -0,0 +1,24 @@ +Assembly File: a.asm + PsiWhiteSpace(' ') + M68kStatementImpl(STATEMENT) + M68kAsmInstructionImpl(ASM_INSTRUCTION) + M68kAsmOpImpl(ASM_OP) + PsiElement(M68kTokenType.MNEMONIC)('movem') + M68kOperandSizeImpl(OPERAND_SIZE) + PsiElement(M68kTokenType.OPSIZE_L)('.l') + PsiWhiteSpace(' ') + M68kRegisterListAddressingModeImpl(REGISTER_LIST_ADDRESSING_MODE) + M68kRegisterRangeImpl(REGISTER_RANGE) + M68kDataRegisterImpl(DATA_REGISTER) + PsiElement(M68kTokenType.DREG)('d0') + PsiElement(M68kTokenType.OP_MINUS)('-') + M68kAddressRegisterImpl(ADDRESS_REGISTER) + PsiElement(M68kTokenType.AREG)('a6') + PsiElement(M68kTokenType.SEPARATOR)(',') + M68kAddressRegisterIndirectPreDecAddressingModeImpl(ADDRESS_REGISTER_INDIRECT_PRE_DEC_ADDRESSING_MODE) + PsiElement(M68kTokenType.OP_MINUS)('-') + PsiElement(M68kTokenType.ROUND_L)('(') + M68kAddressRegisterImpl(ADDRESS_REGISTER) + PsiElement(M68kTokenType.REG_SP)('sp') + PsiElement(M68kTokenType.ROUND_R)(')') + PsiElement(M68kTokenType.EOL)('\n') \ No newline at end of file