Courtesy of Yann:
Bugfix: Special registers for address mode matching only worked with lower case register names. Bugfix: movem with pc-relative mode was missing for weird immediate mode. Bugfix: btst with pc-relative and weird immediate mode was missing. Enhancement: Assembler syntax with implicit immediate 1 for shifts and rotations no longer cause syntax errors.
This commit is contained in:
parent
89bd964fe7
commit
3bb6165a58
@ -148,6 +148,13 @@ are appreciated. They really are, because they do keep me motivated to continue
|
||||
|
||||
## Changelog
|
||||
|
||||
### V0.7 (unreleased)
|
||||
|
||||
- Bugfix: `btst` with pc-relative and weird immediate mode was missing (courtesy of Yann).
|
||||
- Bugfix: `movem` with pc-relative mode was missing for weird immediate mode (courtesy of Yann).
|
||||
- Bugfix: Special registers for address mode matching only worked with lower case register names (courtesy of Yann).
|
||||
- Enhancement: Assembler syntax with implicit immediate 1 for shifts and rotations no longer cause syntax errors (courtesy of Yann).
|
||||
|
||||
### V0.6 (09-Aug-21)
|
||||
|
||||
- Enhancement: `opt` and several other directives (`printt`, `fail` etc.) no longer causes a syntax error when unquoted.
|
||||
|
24
build.gradle
24
build.gradle
@ -7,7 +7,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = 'de.platon42'
|
||||
version = '0.6'
|
||||
version = '0.7'
|
||||
sourceCompatibility = "1.8"
|
||||
targetCompatibility = "1.8"
|
||||
|
||||
@ -57,6 +57,13 @@ runPluginVerifier {
|
||||
|
||||
patchPluginXml {
|
||||
setChangeNotes("""
|
||||
<h4>V0.7 (unreleased)</h4>
|
||||
<ul>
|
||||
<li>Bugfix: 'btst' with pc-relative and weird immediate mode was missing (courtesy of Yann).
|
||||
<li>Bugfix: 'movem' with pc-relative mode was missing for weird immediate mode (courtesy of Yann).
|
||||
<li>Bugfix: Special registers for address mode matching only worked with lower case register names (courtesy of Yann).
|
||||
<li>Enhancement: Assembler syntax with implicit immediate 1 for shifts and rotations no longer cause syntax errors (courtesy of Yann).
|
||||
</ul>
|
||||
<h4>V0.6 (09-Aug-21)</h4>
|
||||
<ul>
|
||||
<li>Enhancement: 'opt' and several other directives ('printt', 'fail' etc.) no longer causes a syntax error when unquoted.
|
||||
@ -71,7 +78,7 @@ patchPluginXml {
|
||||
<ul>
|
||||
<li>Bugfix: movem ISA was wrong regarding movem.w <ea>,<registerlist> (sign extends registers).
|
||||
<li>Cosmetics: Changed Register Flow Documentation wording from 'reads' to 'uses' and from 'modifies' to 'changes'.
|
||||
<li>Bugfix: Minor fix for `andi/eori/ori to ccr` which were not byte sized in ISA.
|
||||
<li>Bugfix: Minor fix for 'andi/eori/ori to ccr' which were not byte sized in ISA.
|
||||
<li>Bugfix: Added alternate condition code tests HS (=CC) and LO (=CS).
|
||||
<li>Performance: Optimized mnemonic lookup.
|
||||
<li>Enhancement: Reworked Instruction Documentation provider, now shows condition codes.
|
||||
@ -79,19 +86,6 @@ patchPluginXml {
|
||||
<li>New: Added inspection to find dead writes to registers!
|
||||
<li>New: Added inspection to warn about unexpected condition code unaffecting instructions before conditional instructions.
|
||||
</ul>
|
||||
<h4>V0.4 (03-Aug-21)</h4>
|
||||
<ul>
|
||||
<li>Notice: Due to major new API use, this plugin no longer works on IDEs >=2019.3.1, but rather requires >=2020.3.
|
||||
<li>Enhancement: Added Structure View filters.
|
||||
<li>New: Added inspection to validate the correctness of a MC68000 instruction regarding operation size and address modes.
|
||||
<li>Bugfix: Added several missing assembler directives (opt, machine, etc.).
|
||||
<li>Bugfix: Uppercase hexadecimal literals were not parsed (JFlex bug?).
|
||||
<li>Bugfix: Interpretation of register lists was wrong in BNF.
|
||||
<li>New: Added Documentation Provider for symbol definitions (shows assigned declaration).
|
||||
<li>New: Added Documentation Provider for mnemonics (simple version, generated out of ISA information).
|
||||
<li>Bugfix: Macro definitions with colons and without space supported (as found in P61a source).
|
||||
<li>New: When asking for documentation on registers, a code flow analysis is done. Cool stuff!
|
||||
</ul>
|
||||
<p>Full changelog available at <a href="https://github.com/chrisly42/mc68000-asm-plugin#changelog">Github project site</a>.</p>
|
||||
""")
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ enum class AddressMode(val description: String, val syntax: String) {
|
||||
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)"),
|
||||
PROGRAM_COUNTER_INDIRECT_WITH_INDEX("program counter indirect with index", "(d8,PC,Xn)"),
|
||||
SPECIAL_REGISTER_DIRECT("special register", "ccr|usp|vbr"),
|
||||
SPECIAL_REGISTER_DIRECT("special register", "sr|ccr|usp|vbr"),
|
||||
REGISTER_LIST("register list", "list"),
|
||||
IMMEDIATE_DATA("immediate", "#<xxx>"),
|
||||
ABSOLUTE_ADDRESS("absolute short/long", "(xxx).w|l")
|
||||
@ -202,6 +202,18 @@ object M68kIsa {
|
||||
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX,
|
||||
)
|
||||
|
||||
private val ALL_EXCEPT_AREG_AND_DREG = setOf(
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT,
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_POST_INC,
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC,
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT,
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX,
|
||||
AddressMode.ABSOLUTE_ADDRESS,
|
||||
AddressMode.IMMEDIATE_DATA,
|
||||
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_DISPLACEMENT,
|
||||
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX,
|
||||
)
|
||||
|
||||
private val INDIRECT_MODES = setOf(
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT,
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_POST_INC,
|
||||
@ -256,33 +268,39 @@ object M68kIsa {
|
||||
private val ASD_LSD_MODES = listOf(
|
||||
AllowedAdrMode(DREG_ONLY, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE, affectedCc = cc("*****")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, modInfo = RWM_MODIFY_OP2_OPSIZE, affectedCc = cc("*****")),
|
||||
AllowedAdrMode(INDIRECT_MODES, null, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("*****")),
|
||||
AllowedAdrMode(INDIRECT_MODES, null, size = OP_SIZE_W, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("*****")),
|
||||
// not an official address mode, but supported by assembler (implicit #1)
|
||||
AllowedAdrMode(DREG_ONLY, null, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("*****"))
|
||||
)
|
||||
|
||||
private val ROD_MODES = listOf(
|
||||
AllowedAdrMode(DREG_ONLY, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE, affectedCc = cc("-**0*")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, modInfo = RWM_MODIFY_OP2_OPSIZE, affectedCc = cc("-**0*")),
|
||||
AllowedAdrMode(INDIRECT_MODES, null, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("-**0*")),
|
||||
AllowedAdrMode(INDIRECT_MODES, null, size = OP_SIZE_W, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("-**0*")),
|
||||
// not an official address mode, but supported by assembler (implicit #1)
|
||||
AllowedAdrMode(DREG_ONLY, null, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("-**0*")),
|
||||
)
|
||||
|
||||
private val ROXD_MODES = listOf(
|
||||
AllowedAdrMode(DREG_ONLY, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE, affectedCc = cc("***0*"), testedCc = cc("?----")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, modInfo = RWM_MODIFY_OP2_OPSIZE, affectedCc = cc("***0*"), testedCc = cc("?----")),
|
||||
AllowedAdrMode(INDIRECT_MODES, null, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("***0*"), testedCc = cc("?----")),
|
||||
AllowedAdrMode(INDIRECT_MODES, null, size = OP_SIZE_W, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("***0*"), testedCc = cc("?----")),
|
||||
// not an official address mode, but supported by assembler (implicit #1)
|
||||
AllowedAdrMode(DREG_ONLY, null, modInfo = RWM_MODIFY_OP1_OPSIZE, affectedCc = cc("***0*"), testedCc = cc("?----")),
|
||||
)
|
||||
|
||||
private val BCHG_BCLR_BSET_MODES = listOf(
|
||||
AllowedAdrMode(DREG_ONLY, DREG_ONLY, OP_SIZE_L, modInfo = RWM_READ_OP1_B or RWM_MODIFY_OP2_L, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(DREG_ONLY, INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_READ_OP1_B or RWM_MODIFY_OP2_B, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, OP_SIZE_L, modInfo = RWM_MODIFY_OP2_L, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_MODIFY_OP2_B, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_AND_DREG, OP_SIZE_B, modInfo = RWM_MODIFY_OP2_B, affectedCc = cc("--*--")),
|
||||
)
|
||||
|
||||
private val BTST_MODES = listOf(
|
||||
AllowedAdrMode(DREG_ONLY, DREG_ONLY, OP_SIZE_L, modInfo = RWM_READ_OP1_B or RWM_READ_OP2_L, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(DREG_ONLY, INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_READ_OP1_B or RWM_READ_OP2_B, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(DREG_ONLY, ALL_EXCEPT_AREG_AND_DREG, OP_SIZE_B, modInfo = RWM_READ_OP1_B or RWM_READ_OP2_B, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, OP_SIZE_L, modInfo = RWM_READ_OP2_L, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_READ_OP2_B, affectedCc = cc("--*--")),
|
||||
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_AND_DREG, OP_SIZE_B, modInfo = RWM_READ_OP2_B, affectedCc = cc("--*--")),
|
||||
)
|
||||
|
||||
private val conditionCodes =
|
||||
@ -354,7 +372,9 @@ object M68kIsa {
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_POST_INC,
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT,
|
||||
AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX,
|
||||
AddressMode.ABSOLUTE_ADDRESS
|
||||
AddressMode.ABSOLUTE_ADDRESS,
|
||||
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_DISPLACEMENT,
|
||||
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX
|
||||
),
|
||||
setOf(AddressMode.IMMEDIATE_DATA),
|
||||
OP_SIZE_WL,
|
||||
@ -944,5 +964,5 @@ object M68kIsa {
|
||||
private fun isAddressModeMatching(am: AllowedAdrMode, op1: AddressMode?, op2: AddressMode?, specialReg: String?) =
|
||||
((((op1 == null) && (am.op1 == null)) || am.op1?.contains(op1) ?: false)
|
||||
&& (((op2 == null) && (am.op2 == null)) || am.op2?.contains(op2) ?: false)
|
||||
&& ((specialReg == null) || (specialReg == am.specialReg)))
|
||||
&& ((specialReg == null) || (specialReg.equals(am.specialReg, true))))
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<fileType name="MC68000 Assembler" implementationClass="de.platon42.intellij.plugins.m68k.M68kFileType"
|
||||
fieldName="INSTANCE" language="MC68000" extensions="asm;ASM;s;S;i"/>
|
||||
fieldName="INSTANCE" language="MC68000" extensions="asm;s;i"/>
|
||||
<lang.parserDefinition language="MC68000"
|
||||
implementationClass="de.platon42.intellij.plugins.m68k.parser.M68kParserDefinition"/>
|
||||
<lang.syntaxHighlighterFactory language="MC68000"
|
||||
@ -47,7 +47,7 @@
|
||||
<stubIndex implementation="de.platon42.intellij.plugins.m68k.stubs.M68kGlobalLabelStubIndex"/>
|
||||
<stubIndex implementation="de.platon42.intellij.plugins.m68k.stubs.M68kSymbolDefinitionStubIndex"/>
|
||||
<stubIndex implementation="de.platon42.intellij.plugins.m68k.stubs.M68kMacroDefinitionStubIndex"/>
|
||||
<psi.referenceContributor implementation="de.platon42.intellij.plugins.m68k.refs.M68kReferenceContributor"/>
|
||||
<psi.referenceContributor language="MC68000" implementation="de.platon42.intellij.plugins.m68k.refs.M68kReferenceContributor"/>
|
||||
<gotoSymbolContributor implementation="de.platon42.intellij.plugins.m68k.refs.M68kChooseByNameContributor"/>
|
||||
<renameInputValidator implementation="de.platon42.intellij.plugins.m68k.psi.M68kRenameInputValidator"/>
|
||||
<include.provider implementation="de.platon42.intellij.plugins.m68k.scanner.M68kIncludeFileProvider"/>
|
||||
|
@ -87,6 +87,11 @@ internal class AddressingModesTest : AbstractParsingTest() {
|
||||
testGoodSyntax(testCase, " move.l 4.w,a6\n")
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun btst_quirk(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
|
||||
testGoodSyntax(testCase, " btst #5,#42\n btst d0,#42")
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun movem_register_list(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
|
||||
testGoodSyntax(testCase, " movem.l d0-d2/d4/a0/a2-a3/a5,-(sp)\n")
|
||||
@ -118,7 +123,7 @@ internal class AddressingModesTest : AbstractParsingTest() {
|
||||
internal fun special_register_move(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
|
||||
testGoodSyntax(
|
||||
testCase, " move.l usp,a0\n"
|
||||
+ " move.l a5,usp\n"
|
||||
+ " move.l a5,USP\n"
|
||||
)
|
||||
}
|
||||
|
||||
|
31
src/test/resources/parser/addressingmodes/btst_quirk.txt
Normal file
31
src/test/resources/parser/addressingmodes/btst_quirk.txt
Normal file
@ -0,0 +1,31 @@
|
||||
Assembly File: a.asm
|
||||
PsiWhiteSpace(' ')
|
||||
M68kStatementImpl(STATEMENT)
|
||||
M68kAsmInstructionImpl(ASM_INSTRUCTION)
|
||||
M68kAsmOpImpl(ASM_OP)
|
||||
PsiElement(M68kTokenType.MNEMONIC)('btst')
|
||||
PsiWhiteSpace(' ')
|
||||
M68kImmediateDataImpl(IMMEDIATE_DATA)
|
||||
PsiElement(M68kTokenType.HASH)('#')
|
||||
M68kLiteralExprImpl(LITERAL_EXPR)
|
||||
PsiElement(M68kTokenType.DECIMAL)('5')
|
||||
PsiElement(M68kTokenType.SEPARATOR)(',')
|
||||
M68kImmediateDataImpl(IMMEDIATE_DATA)
|
||||
PsiElement(M68kTokenType.HASH)('#')
|
||||
M68kLiteralExprImpl(LITERAL_EXPR)
|
||||
PsiElement(M68kTokenType.DECIMAL)('42')
|
||||
PsiElement(M68kTokenType.EOL)('\n')
|
||||
PsiWhiteSpace(' ')
|
||||
M68kStatementImpl(STATEMENT)
|
||||
M68kAsmInstructionImpl(ASM_INSTRUCTION)
|
||||
M68kAsmOpImpl(ASM_OP)
|
||||
PsiElement(M68kTokenType.MNEMONIC)('btst')
|
||||
PsiWhiteSpace(' ')
|
||||
M68kDataRegisterDirectAddressingModeImpl(DATA_REGISTER_DIRECT_ADDRESSING_MODE)
|
||||
M68kDataRegisterImpl(DATA_REGISTER)
|
||||
PsiElement(M68kTokenType.DREG)('d0')
|
||||
PsiElement(M68kTokenType.SEPARATOR)(',')
|
||||
M68kImmediateDataImpl(IMMEDIATE_DATA)
|
||||
PsiElement(M68kTokenType.HASH)('#')
|
||||
M68kLiteralExprImpl(LITERAL_EXPR)
|
||||
PsiElement(M68kTokenType.DECIMAL)('42')
|
@ -29,5 +29,5 @@ Assembly File: a.asm
|
||||
PsiElement(M68kTokenType.SEPARATOR)(',')
|
||||
M68kSpecialRegisterDirectAddressingModeImpl(SPECIAL_REGISTER_DIRECT_ADDRESSING_MODE)
|
||||
M68kSpecialRegisterImpl(SPECIAL_REGISTER)
|
||||
PsiElement(M68kTokenType.REG_USP)('usp')
|
||||
PsiElement(M68kTokenType.REG_USP)('USP')
|
||||
PsiElement(M68kTokenType.EOL)('\n')
|
Loading…
Reference in New Issue
Block a user