Added support for movem with register list crossing from data to address (e.g. d0-a6) as found in p61a source.
This commit is contained in:
parent
19e3b519db
commit
7744b589d4
@ -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) {
|
public static boolean RegisterRange(PsiBuilder b, int l) {
|
||||||
if (!recursion_guard_(b, l, "RegisterRange")) return false;
|
if (!recursion_guard_(b, l, "RegisterRange")) return false;
|
||||||
boolean r;
|
boolean r;
|
||||||
Marker m = enter_section_(b, l, _NONE_, REGISTER_RANGE, "<register range>");
|
Marker m = enter_section_(b, l, _NONE_, REGISTER_RANGE, "<register range>");
|
||||||
r = RegisterRange_0(b, l + 1);
|
r = RegisterRange_0(b, l + 1);
|
||||||
if (!r) r = RegisterRange_1(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);
|
exit_section_(b, l, m, r, false, null);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -1121,6 +1122,18 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
|||||||
return r;
|
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
|
// REG_CCR | REG_SR | REG_USP | REG_VBR
|
||||||
public static boolean SpecialRegister(PsiBuilder b, int l) {
|
public static boolean SpecialRegister(PsiBuilder b, int l) {
|
||||||
|
@ -42,4 +42,5 @@ public class M68kProgramCounterIndirectWithIndexOldAddressingModeImpl extends M6
|
|||||||
public M68kDataWidth getIndexWidth() {
|
public M68kDataWidth getIndexWidth() {
|
||||||
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
|
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ ProgramCounterIndirectWithIndexNewAddressingMode ::= ROUND_L (expr SEPARATOR)? P
|
|||||||
|
|
||||||
AbsoluteAddressAddressingMode ::= expr AddressSize? !ROUND_L
|
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"
|
name = "register range"
|
||||||
methods = [
|
methods = [
|
||||||
startRegister = "Register[0]"
|
startRegister = "Register[0]"
|
||||||
|
@ -123,8 +123,12 @@ object M68kPsiImplUtil {
|
|||||||
var startReg = Register.getRegFromName(it.startRegister.text)
|
var startReg = Register.getRegFromName(it.startRegister.text)
|
||||||
val endReg = Register.getRegFromName(it.endRegister!!.text)
|
val endReg = Register.getRegFromName(it.endRegister!!.text)
|
||||||
registers.add(startReg)
|
registers.add(startReg)
|
||||||
while (startReg.num < endReg.num) {
|
while ((startReg.num < endReg.num) || (startReg.regname.dropLast(1) != endReg.regname.dropLast(1))) {
|
||||||
startReg = Register.getRegFromName(startReg.regname.dropLast(1) + (startReg.num + 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)
|
registers.add(startReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
@Test
|
||||||
internal fun immediate_data(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
|
internal fun immediate_data(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
|
||||||
testGoodSyntax(testCase, " moveq.l #FOO_BAR,d0\n")
|
testGoodSyntax(testCase, " moveq.l #FOO_BAR,d0\n")
|
||||||
|
@ -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')
|
Loading…
Reference in New Issue
Block a user