Added support for SCALE in index addressing modes.

This commit is contained in:
Chris Hodges 2021-10-07 18:03:12 +02:00
parent 9b93ea05fc
commit 7462c5b02d
16 changed files with 253 additions and 12 deletions

View File

@ -532,13 +532,14 @@ public class M68kParser implements PsiParser, LightPsiParser {
}
/* ********************************************************** */
// DataOrAddressRegister DataWidth?
// DataOrAddressRegister DataWidth? (OP_AR_MUL IndexScale)?
public static boolean IndexRegister(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "IndexRegister")) return false;
boolean r;
Marker m = enter_section_(b, l, _NONE_, INDEX_REGISTER, "<index register>");
r = DataOrAddressRegister(b, l + 1);
r = r && IndexRegister_1(b, l + 1);
r = r && IndexRegister_2(b, l + 1);
exit_section_(b, l, m, r, false, null);
return r;
}
@ -550,6 +551,35 @@ public class M68kParser implements PsiParser, LightPsiParser {
return true;
}
// (OP_AR_MUL IndexScale)?
private static boolean IndexRegister_2(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "IndexRegister_2")) return false;
IndexRegister_2_0(b, l + 1);
return true;
}
// OP_AR_MUL IndexScale
private static boolean IndexRegister_2_0(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "IndexRegister_2_0")) return false;
boolean r;
Marker m = enter_section_(b);
r = consumeToken(b, OP_AR_MUL);
r = r && IndexScale(b, l + 1);
exit_section_(b, m, null, r);
return r;
}
/* ********************************************************** */
// expr
public static boolean IndexScale(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "IndexScale")) return false;
boolean r;
Marker m = enter_section_(b, l, _NONE_, INDEX_SCALE, "<scale value>");
r = expr(b, l + 1, -1);
exit_section_(b, l, m, r, false, null);
return r;
}
/* ********************************************************** */
// AsmInstruction | MacroCall
static boolean Instruction(PsiBuilder b, int l) {

View File

@ -9,6 +9,9 @@ public interface M68kIndexRegister extends M68kPsiElement {
@Nullable
M68kDataWidth getDataWidth();
@Nullable
M68kIndexScale getIndexScale();
@NotNull
M68kRegister getRegister();

View File

@ -0,0 +1,11 @@
// This is a generated file. Not intended for manual editing.
package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
public interface M68kIndexScale extends M68kPsiElement {
@NotNull
M68kExpr getIndexScale();
}

View File

@ -49,6 +49,7 @@ public interface M68kTypes {
IElementType GLOBAL_LABEL = M68kStubElementTypeFactory.stubFactory("GLOBAL_LABEL");
IElementType IMMEDIATE_DATA = new M68kElementType("IMMEDIATE_DATA");
IElementType INDEX_REGISTER = new M68kElementType("INDEX_REGISTER");
IElementType INDEX_SCALE = new M68kElementType("INDEX_SCALE");
IElementType LITERAL_EXPR = new M68kElementType("LITERAL_EXPR");
IElementType LOCAL_LABEL = new M68kElementType("LOCAL_LABEL");
IElementType MACRO_CALL = new M68kElementType("MACRO_CALL");
@ -216,6 +217,8 @@ public interface M68kTypes {
return new M68kImmediateDataImpl(node);
} else if (type == INDEX_REGISTER) {
return new M68kIndexRegisterImpl(node);
} else if (type == INDEX_SCALE) {
return new M68kIndexScaleImpl(node);
} else if (type == LITERAL_EXPR) {
return new M68kLiteralExprImpl(node);
} else if (type == LOCAL_LABEL) {

View File

@ -103,6 +103,10 @@ public class M68kVisitor extends PsiElementVisitor {
visitPsiElement(o);
}
public void visitIndexScale(@NotNull M68kIndexScale o) {
visitPsiElement(o);
}
public void visitLocalLabel(@NotNull M68kLocalLabel o) {
visitNamedElement(o);
}

View File

@ -19,8 +19,8 @@ public class M68kGlobalLabelImpl extends M68kGlobalLabelMixin implements M68kGlo
super(node);
}
public M68kGlobalLabelImpl(@NotNull M68kGlobalLabelStub stub, @NotNull IStubElementType<?, ?> nodeType) {
super(stub, nodeType);
public M68kGlobalLabelImpl(@NotNull M68kGlobalLabelStub stub, @NotNull IStubElementType<?, ?> type) {
super(stub, type);
}
public void accept(@NotNull M68kVisitor visitor) {

View File

@ -31,6 +31,12 @@ public class M68kIndexRegisterImpl extends ASTWrapperPsiElement implements M68kI
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
}
@Override
@Nullable
public M68kIndexScale getIndexScale() {
return PsiTreeUtil.getChildOfType(this, M68kIndexScale.class);
}
@Override
@NotNull
public M68kRegister getRegister() {

View File

@ -0,0 +1,35 @@
// This is a generated file. Not intended for manual editing.
package de.platon42.intellij.plugins.m68k.psi.impl;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import de.platon42.intellij.plugins.m68k.psi.M68kExpr;
import de.platon42.intellij.plugins.m68k.psi.M68kIndexScale;
import de.platon42.intellij.plugins.m68k.psi.M68kVisitor;
import org.jetbrains.annotations.NotNull;
public class M68kIndexScaleImpl extends ASTWrapperPsiElement implements M68kIndexScale {
public M68kIndexScaleImpl(@NotNull ASTNode node) {
super(node);
}
public void accept(@NotNull M68kVisitor visitor) {
visitor.visitIndexScale(this);
}
@Override
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof M68kVisitor) accept((M68kVisitor) visitor);
else super.accept(visitor);
}
@Override
@NotNull
public M68kExpr getIndexScale() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kExpr.class));
}
}

View File

@ -19,8 +19,8 @@ public class M68kMacroDefinitionImpl extends M68kMacroDefinitionMixin implements
super(node);
}
public M68kMacroDefinitionImpl(@NotNull M68kMacroDefinitionStub stub, @NotNull IStubElementType<?, ?> nodeType) {
super(stub, nodeType);
public M68kMacroDefinitionImpl(@NotNull M68kMacroDefinitionStub stub, @NotNull IStubElementType<?, ?> type) {
super(stub, type);
}
public void accept(@NotNull M68kVisitor visitor) {

View File

@ -19,8 +19,8 @@ public class M68kSymbolDefinitionImpl extends M68kSymbolDefinitionMixin implemen
super(node);
}
public M68kSymbolDefinitionImpl(@NotNull M68kSymbolDefinitionStub stub, @NotNull IStubElementType<?, ?> nodeType) {
super(stub, nodeType);
public M68kSymbolDefinitionImpl(@NotNull M68kSymbolDefinitionStub stub, @NotNull IStubElementType<?, ?> type) {
super(stub, type);
}
public void accept(@NotNull M68kVisitor visitor) {

View File

@ -43,7 +43,9 @@ enum class AddressMode(val description: String, val syntax: String) {
ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT("address register indirect with displacement", "(d16,An)"),
PROGRAM_COUNTER_INDIRECT_WITH_DISPLACEMENT("program counter indirect with displacement", "(d16,PC)"),
ADDRESS_REGISTER_INDIRECT_WITH_INDEX("address register indirect with index", "(d8,An,Xn)"),
ADDRESS_REGISTER_INDIRECT_WITH_SCALED_INDEX("address register indirect with scaled index", "(d8,An,Xn*s)"),
PROGRAM_COUNTER_INDIRECT_WITH_INDEX("program counter indirect with index", "(d8,PC,Xn)"),
PROGRAM_COUNTER_INDIRECT_WITH_SCALED_INDEX("program counter indirect with scaled index", "(d8,PC,Xn*s)"),
SPECIAL_REGISTER_DIRECT("special register", "sr|ccr|usp|vbr"),
REGISTER_LIST("register list", "list"),
IMMEDIATE_DATA("immediate", "#<xxx>"),

View File

@ -236,14 +236,23 @@ Register ::= DataRegister | AddressRegister | SpecialRegister
private DataOrAddressRegister ::= DataRegister | AddressRegister { name = "data or address register"}
IndexRegister ::= DataOrAddressRegister DataWidth?
IndexRegister ::= DataOrAddressRegister DataWidth? (OP_AR_MUL IndexScale)?
{
name = "index register"
methods = [
indexRegister = "DataOrAddressRegister"
isLongWidth
]
}
IndexScale ::= expr
{
name = "scale value"
methods = [
indexScale = "expr"
]
}
AddressingMode ::= ImmediateData
| AddressRegisterIndirectPreDecAddressingMode
| AddressRegisterIndirectPostIncAddressingMode
@ -268,6 +277,7 @@ AddressRegisterDirectAddressingMode ::= AddressRegister !(OP_MINUS|OP_AR_DIV)
AddressRegisterIndirectAddressingMode ::= ROUND_L AddressRegister ROUND_R !OP_PLUS { implements = "de.platon42.intellij.plugins.m68k.psi.M68kWithAddressRegisterIndirect" }
AddressRegisterIndirectPostIncAddressingMode ::= ROUND_L AddressRegister ROUND_R OP_PLUS { implements = "de.platon42.intellij.plugins.m68k.psi.M68kWithAddressRegisterIndirect" }
AddressRegisterIndirectPreDecAddressingMode ::= OP_MINUS ROUND_L AddressRegister ROUND_R { implements = "de.platon42.intellij.plugins.m68k.psi.M68kWithAddressRegisterIndirect" }
AddressRegisterIndirectWithDisplacementOldAddressingMode ::= expr ROUND_L AddressRegister ROUND_R
{
implements = [
@ -278,6 +288,7 @@ AddressRegisterIndirectWithDisplacementOldAddressingMode ::= expr ROUND_L Addres
displacement = "expr"
]
}
AddressRegisterIndirectWithDisplacementNewAddressingMode ::= ROUND_L expr SEPARATOR AddressRegister ROUND_R
{
implements = [

View File

@ -12,12 +12,12 @@ object M68kAddressModeUtil {
is M68kAddressRegisterIndirectPreDecAddressingMode -> AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC
is M68kAddressRegisterIndirectWithDisplacementNewAddressingMode -> AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT
is M68kAddressRegisterIndirectWithDisplacementOldAddressingMode -> AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT
is M68kAddressRegisterIndirectWithIndexNewAddressingMode -> AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX
is M68kAddressRegisterIndirectWithIndexOldAddressingMode -> AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX
is M68kAddressRegisterIndirectWithIndexNewAddressingMode -> if (hasScale(addressingMode)) AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_SCALED_INDEX else AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX
is M68kAddressRegisterIndirectWithIndexOldAddressingMode -> if (hasScale(addressingMode)) AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_SCALED_INDEX else AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX
is M68kProgramCounterIndirectWithDisplacementNewAddressingMode -> AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_DISPLACEMENT
is M68kProgramCounterIndirectWithDisplacementOldAddressingMode -> AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_DISPLACEMENT
is M68kProgramCounterIndirectWithIndexNewAddressingMode -> AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX
is M68kProgramCounterIndirectWithIndexOldAddressingMode -> AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX
is M68kProgramCounterIndirectWithIndexNewAddressingMode -> if (hasScale(addressingMode)) AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_SCALED_INDEX else AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX
is M68kProgramCounterIndirectWithIndexOldAddressingMode -> if (hasScale(addressingMode)) AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_SCALED_INDEX else AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX
is M68kSpecialRegisterDirectAddressingMode -> AddressMode.SPECIAL_REGISTER_DIRECT
is M68kDataRegisterDirectAddressingMode -> AddressMode.DATA_REGISTER_DIRECT
is M68kAddressRegisterDirectAddressingMode -> AddressMode.ADDRESS_REGISTER_DIRECT
@ -27,6 +27,8 @@ object M68kAddressModeUtil {
}
}
private fun hasScale(addressingMode: M68kWithIndexRegister) = addressingMode.indexRegister.indexScale != null
fun getOtherReadWriteModifyRegisters(rwm: Int): List<Pair<Register, Int>> {
if (rwm and RWM_MODIFY_STACK > 0) {
return listOf(Register.A7 to RWM_MODIFY_L)

View File

@ -52,6 +52,16 @@ internal class AddressingModesTest : AbstractParsingTest() {
testGoodSyntax(testCase, " move.l (sp,d0.w),(a1,a3)\n")
}
@Test
internal fun register_indirect_with_scaled_index_and_offset_old_syntax(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
testGoodSyntax(testCase, " move.l -4+foo(sp,d0.w*8),(10*20+4)(a1,a3*4)\n")
}
@Test
internal fun register_indirect_with_scaled_index_and_offset_new_syntax(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
testGoodSyntax(testCase, " move.l (-4+foo,sp,a0*1),((10*20+4),a1,d5.l*2)\n")
}
@Test
internal fun pc_indirect_with_offset_old_syntax(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
testGoodSyntax(testCase, " move.l -4*4(pc),+4(pc)\n")

View File

@ -0,0 +1,63 @@
Assembly File: a.asm
PsiWhiteSpace(' ')
M68kStatementImpl(STATEMENT)
M68kAsmInstructionImpl(ASM_INSTRUCTION)
M68kAsmOpImpl(ASM_OP)
PsiElement(M68kTokenType.MNEMONIC)('move')
M68kOperandSizeImpl(OPERAND_SIZE)
PsiElement(M68kTokenType.OPSIZE_L)('.l')
PsiWhiteSpace(' ')
M68kAddressRegisterIndirectWithIndexNewAddressingModeImpl(ADDRESS_REGISTER_INDIRECT_WITH_INDEX_NEW_ADDRESSING_MODE)
PsiElement(M68kTokenType.ROUND_L)('(')
M68kBinaryAddExprImpl(BINARY_ADD_EXPR)
M68kUnaryMinusExprImpl(UNARY_MINUS_EXPR)
PsiElement(M68kTokenType.OP_MINUS)('-')
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('4')
PsiElement(M68kTokenType.OP_PLUS)('+')
M68kRefExprImpl(REF_EXPR)
M68kSymbolReferenceImpl(SYMBOL_REFERENCE)
PsiElement(M68kTokenType.SYMBOL)('foo')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.REG_SP)('sp')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kIndexRegisterImpl(INDEX_REGISTER)
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a0')
PsiElement(M68kTokenType.OP_AR_MUL)('*')
M68kIndexScaleImpl(INDEX_SCALE)
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('1')
PsiElement(M68kTokenType.ROUND_R)(')')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kAddressRegisterIndirectWithIndexNewAddressingModeImpl(ADDRESS_REGISTER_INDIRECT_WITH_INDEX_NEW_ADDRESSING_MODE)
PsiElement(M68kTokenType.ROUND_L)('(')
M68kParenExprImpl(PAREN_EXPR)
PsiElement(M68kTokenType.ROUND_L)('(')
M68kBinaryAddExprImpl(BINARY_ADD_EXPR)
M68kBinaryMulExprImpl(BINARY_MUL_EXPR)
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('10')
PsiElement(M68kTokenType.OP_AR_MUL)('*')
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('20')
PsiElement(M68kTokenType.OP_PLUS)('+')
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('4')
PsiElement(M68kTokenType.ROUND_R)(')')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a1')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kIndexRegisterImpl(INDEX_REGISTER)
M68kDataRegisterImpl(DATA_REGISTER)
PsiElement(M68kTokenType.DREG)('d5')
M68kDataWidthImpl(DATA_WIDTH)
PsiElement(M68kTokenType.OPSIZE_L)('.l')
PsiElement(M68kTokenType.OP_AR_MUL)('*')
M68kIndexScaleImpl(INDEX_SCALE)
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('2')
PsiElement(M68kTokenType.ROUND_R)(')')
PsiElement(M68kTokenType.EOL)('\n')

View File

@ -0,0 +1,61 @@
Assembly File: a.asm
PsiWhiteSpace(' ')
M68kStatementImpl(STATEMENT)
M68kAsmInstructionImpl(ASM_INSTRUCTION)
M68kAsmOpImpl(ASM_OP)
PsiElement(M68kTokenType.MNEMONIC)('move')
M68kOperandSizeImpl(OPERAND_SIZE)
PsiElement(M68kTokenType.OPSIZE_L)('.l')
PsiWhiteSpace(' ')
M68kAddressRegisterIndirectWithIndexOldAddressingModeImpl(ADDRESS_REGISTER_INDIRECT_WITH_INDEX_OLD_ADDRESSING_MODE)
M68kBinaryAddExprImpl(BINARY_ADD_EXPR)
M68kUnaryMinusExprImpl(UNARY_MINUS_EXPR)
PsiElement(M68kTokenType.OP_MINUS)('-')
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('4')
PsiElement(M68kTokenType.OP_PLUS)('+')
M68kRefExprImpl(REF_EXPR)
M68kSymbolReferenceImpl(SYMBOL_REFERENCE)
PsiElement(M68kTokenType.SYMBOL)('foo')
PsiElement(M68kTokenType.ROUND_L)('(')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.REG_SP)('sp')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kIndexRegisterImpl(INDEX_REGISTER)
M68kDataRegisterImpl(DATA_REGISTER)
PsiElement(M68kTokenType.DREG)('d0')
M68kDataWidthImpl(DATA_WIDTH)
PsiElement(M68kTokenType.OPSIZE_W)('.w')
PsiElement(M68kTokenType.OP_AR_MUL)('*')
M68kIndexScaleImpl(INDEX_SCALE)
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('8')
PsiElement(M68kTokenType.ROUND_R)(')')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kAddressRegisterIndirectWithIndexOldAddressingModeImpl(ADDRESS_REGISTER_INDIRECT_WITH_INDEX_OLD_ADDRESSING_MODE)
M68kParenExprImpl(PAREN_EXPR)
PsiElement(M68kTokenType.ROUND_L)('(')
M68kBinaryAddExprImpl(BINARY_ADD_EXPR)
M68kBinaryMulExprImpl(BINARY_MUL_EXPR)
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('10')
PsiElement(M68kTokenType.OP_AR_MUL)('*')
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('20')
PsiElement(M68kTokenType.OP_PLUS)('+')
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('4')
PsiElement(M68kTokenType.ROUND_R)(')')
PsiElement(M68kTokenType.ROUND_L)('(')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a1')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kIndexRegisterImpl(INDEX_REGISTER)
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a3')
PsiElement(M68kTokenType.OP_AR_MUL)('*')
M68kIndexScaleImpl(INDEX_SCALE)
M68kLiteralExprImpl(LITERAL_EXPR)
PsiElement(M68kTokenType.DECIMAL)('4')
PsiElement(M68kTokenType.ROUND_R)(')')
PsiElement(M68kTokenType.EOL)('\n')