Bugfix: Interpretation of register lists was wrong in BNF.

Massively extended M68kIsa with description on register modifications (not yet used in production code).
Changed BNF for additional AddressingMode interfaces.
This commit is contained in:
Chris Hodges 2021-08-01 10:08:01 +02:00
parent ce3cdbbed6
commit 09a4e62c7c
37 changed files with 680 additions and 184 deletions

View File

@ -42,14 +42,14 @@ it's "good enough" to get started, and I can return to demo coding with its curr
- No support for register replacement (e.g. registers replaced by `EQUR` or `EQURL` will cause syntax errors)
- While the Lexer supports the -spaces option (where a space introduces a comment), this cannot be configured yet (default is off).
- No support for other processor instructions, FPU or 68020+ address modes.
- No semantic checking for allowed address modes or data widths yet.
- For versions < V0.4: No semantic checking for allowed address modes or data widths yet.
- Unit Test coverage is not as good as it could be (ahem).
- Missing but planned features:
- Macro evaluation on invocation
- Folding
- Semantic inspections
- Quick fixes
- Formatter + Code Style Settings
- Semantic inspections
- Quick fixes
- Formatter + Code Style Settings
- Register use analysis (but this only makes sense after macro evaluation)
- Cycle counting
@ -74,6 +74,7 @@ make it work with JUnit 5. Feel free to use the code (in package ```de.platon42.
- New: Added inspection to validate the correctness of a MC68000 instruction regarding operation size and address modes.
- Bugfix: Added several missing assembler directives (`opt`, `machine`, etc.).
- Bugfix: Uppercase hexadecimal literals were not parsed (JFlex bug?).
- Bugfix: Interpretation of register lists was wrong in BNF.
### V0.3 (28-Jul-21)

View File

@ -31,7 +31,10 @@ dependencies {
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += "-Xjvm-default=all"
}
}
compileTestKotlin {
@ -63,6 +66,7 @@ patchPluginXml {
<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.
</ul>
<h4>V0.3 (28-Jul-21)</h4>
<ul>

View File

@ -1026,27 +1026,27 @@ public class M68kParser implements PsiParser, LightPsiParser {
}
/* ********************************************************** */
// (DataOrAddressRegister|RegisterRange) ((OP_AR_DIV|OP_MINUS) (DataOrAddressRegister|RegisterRange))*
// (RegisterRange|DataOrAddressRegister) (OP_AR_DIV (RegisterRange|DataOrAddressRegister))*
public static boolean RegisterListAddressingMode(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterListAddressingMode")) return false;
boolean r;
Marker m = enter_section_(b, l, _NONE_, REGISTER_LIST_ADDRESSING_MODE, "<AddressingMode>");
Marker m = enter_section_(b, l, _NONE_, REGISTER_LIST_ADDRESSING_MODE, "<register list>");
r = RegisterListAddressingMode_0(b, l + 1);
r = r && RegisterListAddressingMode_1(b, l + 1);
exit_section_(b, l, m, r, false, null);
return r;
}
// DataOrAddressRegister|RegisterRange
// RegisterRange|DataOrAddressRegister
private static boolean RegisterListAddressingMode_0(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterListAddressingMode_0")) return false;
boolean r;
r = DataOrAddressRegister(b, l + 1);
if (!r) r = RegisterRange(b, l + 1);
r = RegisterRange(b, l + 1);
if (!r) r = DataOrAddressRegister(b, l + 1);
return r;
}
// ((OP_AR_DIV|OP_MINUS) (DataOrAddressRegister|RegisterRange))*
// (OP_AR_DIV (RegisterRange|DataOrAddressRegister))*
private static boolean RegisterListAddressingMode_1(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterListAddressingMode_1")) return false;
while (true) {
@ -1057,44 +1057,58 @@ public class M68kParser implements PsiParser, LightPsiParser {
return true;
}
// (OP_AR_DIV|OP_MINUS) (DataOrAddressRegister|RegisterRange)
// OP_AR_DIV (RegisterRange|DataOrAddressRegister)
private static boolean RegisterListAddressingMode_1_0(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterListAddressingMode_1_0")) return false;
boolean r;
Marker m = enter_section_(b);
r = RegisterListAddressingMode_1_0_0(b, l + 1);
r = consumeTokenFast(b, OP_AR_DIV);
r = r && RegisterListAddressingMode_1_0_1(b, l + 1);
exit_section_(b, m, null, r);
return r;
}
// OP_AR_DIV|OP_MINUS
private static boolean RegisterListAddressingMode_1_0_0(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterListAddressingMode_1_0_0")) return false;
boolean r;
r = consumeTokenFast(b, OP_AR_DIV);
if (!r) r = consumeTokenFast(b, OP_MINUS);
return r;
}
// DataOrAddressRegister|RegisterRange
// RegisterRange|DataOrAddressRegister
private static boolean RegisterListAddressingMode_1_0_1(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterListAddressingMode_1_0_1")) return false;
boolean r;
r = DataOrAddressRegister(b, l + 1);
if (!r) r = RegisterRange(b, l + 1);
r = RegisterRange(b, l + 1);
if (!r) r = DataOrAddressRegister(b, l + 1);
return r;
}
/* ********************************************************** */
// DataOrAddressRegister OP_MINUS DataOrAddressRegister
static boolean RegisterRange(PsiBuilder b, int l) {
// (DataRegister OP_MINUS DataRegister) | (AddressRegister 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, "<register range>");
r = RegisterRange_0(b, l + 1);
if (!r) r = RegisterRange_1(b, l + 1);
exit_section_(b, l, m, r, false, null);
return r;
}
// DataRegister OP_MINUS DataRegister
private static boolean RegisterRange_0(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterRange_0")) return false;
boolean r;
Marker m = enter_section_(b);
r = DataOrAddressRegister(b, l + 1);
r = DataRegister(b, l + 1);
r = r && consumeToken(b, OP_MINUS);
r = r && DataOrAddressRegister(b, l + 1);
r = r && DataRegister(b, l + 1);
exit_section_(b, m, null, r);
return r;
}
// AddressRegister OP_MINUS AddressRegister
private static boolean RegisterRange_1(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "RegisterRange_1")) return false;
boolean r;
Marker m = enter_section_(b);
r = AddressRegister(b, l + 1);
r = r && consumeToken(b, OP_MINUS);
r = r && AddressRegister(b, l + 1);
exit_section_(b, m, null, r);
return r;
}

View File

@ -3,7 +3,7 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
public interface M68kAddressRegisterIndirectAddressingMode extends M68kAddressingMode {
public interface M68kAddressRegisterIndirectAddressingMode extends M68kAddressingMode, M68kWithAddressRegisterIndirect {
@NotNull
M68kAddressRegister getAddressRegister();

View File

@ -3,7 +3,7 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
public interface M68kAddressRegisterIndirectPostIncAddressingMode extends M68kAddressingMode {
public interface M68kAddressRegisterIndirectPostIncAddressingMode extends M68kAddressingMode, M68kWithAddressRegisterIndirect {
@NotNull
M68kAddressRegister getAddressRegister();

View File

@ -3,7 +3,7 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
public interface M68kAddressRegisterIndirectPreDecAddressingMode extends M68kAddressingMode {
public interface M68kAddressRegisterIndirectPreDecAddressingMode extends M68kAddressingMode, M68kWithAddressRegisterIndirect {
@NotNull
M68kAddressRegister getAddressRegister();

View File

@ -3,12 +3,12 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
public interface M68kAddressRegisterIndirectWithDisplacementNewAddressingMode extends M68kAddressingMode {
public interface M68kAddressRegisterIndirectWithDisplacementNewAddressingMode extends M68kAddressingMode, M68kWithAddressRegisterIndirect, M68kWithDisplacement {
@NotNull
M68kAddressRegister getAddressRegister();
@NotNull
M68kExpr getExpr();
M68kExpr getDisplacement();
}

View File

@ -3,12 +3,12 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
public interface M68kAddressRegisterIndirectWithDisplacementOldAddressingMode extends M68kAddressingMode {
public interface M68kAddressRegisterIndirectWithDisplacementOldAddressingMode extends M68kAddressingMode, M68kWithAddressRegisterIndirect, M68kWithDisplacement {
@NotNull
M68kAddressRegister getAddressRegister();
@NotNull
M68kExpr getExpr();
M68kExpr getDisplacement();
}

View File

@ -4,18 +4,18 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface M68kAddressRegisterIndirectWithIndexNewAddressingMode extends M68kAddressingMode {
public interface M68kAddressRegisterIndirectWithIndexNewAddressingMode extends M68kAddressingMode, M68kWithAddressRegisterIndirect, M68kWithDisplacement, M68kWithIndexRegister {
@NotNull
M68kAddressRegister getAddressRegister();
@Nullable
M68kDataWidth getDataWidth();
M68kExpr getDisplacement();
@NotNull
M68kRegister getRegister();
M68kRegister getIndexRegister();
@Nullable
M68kExpr getExpr();
M68kDataWidth getIndexWidth();
}

View File

@ -4,18 +4,18 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface M68kAddressRegisterIndirectWithIndexOldAddressingMode extends M68kAddressingMode {
public interface M68kAddressRegisterIndirectWithIndexOldAddressingMode extends M68kAddressingMode, M68kWithAddressRegisterIndirect, M68kWithDisplacement, M68kWithIndexRegister {
@NotNull
M68kAddressRegister getAddressRegister();
@Nullable
M68kDataWidth getDataWidth();
M68kExpr getDisplacement();
@NotNull
M68kRegister getRegister();
M68kRegister getIndexRegister();
@Nullable
M68kExpr getExpr();
M68kDataWidth getIndexWidth();
}

View File

@ -3,9 +3,9 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
public interface M68kProgramCounterIndirectWithDisplacementNewAddressingMode extends M68kAddressingMode {
public interface M68kProgramCounterIndirectWithDisplacementNewAddressingMode extends M68kAddressingMode, M68kWithDisplacement {
@NotNull
M68kExpr getExpr();
M68kExpr getDisplacement();
}

View File

@ -3,9 +3,9 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.Nullable;
public interface M68kProgramCounterIndirectWithDisplacementOldAddressingMode extends M68kAddressingMode {
public interface M68kProgramCounterIndirectWithDisplacementOldAddressingMode extends M68kAddressingMode, M68kWithDisplacement {
@Nullable
M68kExpr getExpr();
M68kExpr getDisplacement();
}

View File

@ -4,15 +4,15 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface M68kProgramCounterIndirectWithIndexNewAddressingMode extends M68kAddressingMode {
public interface M68kProgramCounterIndirectWithIndexNewAddressingMode extends M68kAddressingMode, M68kWithDisplacement, M68kWithIndexRegister {
@Nullable
M68kDataWidth getDataWidth();
M68kExpr getDisplacement();
@NotNull
M68kRegister getRegister();
M68kRegister getIndexRegister();
@Nullable
M68kExpr getExpr();
M68kDataWidth getIndexWidth();
}

View File

@ -4,15 +4,15 @@ package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface M68kProgramCounterIndirectWithIndexOldAddressingMode extends M68kAddressingMode {
public interface M68kProgramCounterIndirectWithIndexOldAddressingMode extends M68kAddressingMode, M68kWithDisplacement, M68kWithIndexRegister {
@Nullable
M68kDataWidth getDataWidth();
M68kExpr getDisplacement();
@NotNull
M68kRegister getRegister();
M68kRegister getIndexRegister();
@Nullable
M68kExpr getExpr();
M68kDataWidth getIndexWidth();
}

View File

@ -1,13 +1,21 @@
// This is a generated file. Not intended for manual editing.
package de.platon42.intellij.plugins.m68k.psi;
import de.platon42.intellij.plugins.m68k.asm.Register;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
public interface M68kRegisterListAddressingMode extends M68kAddressingMode {
@NotNull
List<M68kRegister> getRegisterList();
@NotNull
List<M68kRegisterRange> getRegisterRangeList();
@NotNull
Set<Register> getRegisters();
}

View File

@ -0,0 +1,20 @@
// This is a generated file. Not intended for manual editing.
package de.platon42.intellij.plugins.m68k.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface M68kRegisterRange extends M68kPsiElement {
@NotNull
List<M68kRegister> getRegisterList();
@NotNull
M68kRegister getStartRegister();
@Nullable
M68kRegister getEndRegister();
}

View File

@ -65,6 +65,7 @@ public interface M68kTypes {
IElementType REF_EXPR = new M68kElementType("REF_EXPR");
IElementType REGISTER = new M68kElementType("REGISTER");
IElementType REGISTER_LIST_ADDRESSING_MODE = new M68kElementType("REGISTER_LIST_ADDRESSING_MODE");
IElementType REGISTER_RANGE = new M68kElementType("REGISTER_RANGE");
IElementType SPECIAL_REGISTER = new M68kElementType("SPECIAL_REGISTER");
IElementType SPECIAL_REGISTER_DIRECT_ADDRESSING_MODE = new M68kElementType("SPECIAL_REGISTER_DIRECT_ADDRESSING_MODE");
IElementType STATEMENT = new M68kElementType("STATEMENT");
@ -243,6 +244,8 @@ public interface M68kTypes {
return new M68kRefExprImpl(node);
} else if (type == REGISTER_LIST_ADDRESSING_MODE) {
return new M68kRegisterListAddressingModeImpl(node);
} else if (type == REGISTER_RANGE) {
return new M68kRegisterRangeImpl(node);
} else if (type == SPECIAL_REGISTER) {
return new M68kSpecialRegisterImpl(node);
} else if (type == SPECIAL_REGISTER_DIRECT_ADDRESSING_MODE) {

View File

@ -20,30 +20,43 @@ public class M68kVisitor extends PsiElementVisitor {
public void visitAddressRegisterIndirectAddressingMode(@NotNull M68kAddressRegisterIndirectAddressingMode o) {
visitAddressingMode(o);
// visitWithAddressRegisterIndirect(o);
}
public void visitAddressRegisterIndirectPostIncAddressingMode(@NotNull M68kAddressRegisterIndirectPostIncAddressingMode o) {
visitAddressingMode(o);
// visitWithAddressRegisterIndirect(o);
}
public void visitAddressRegisterIndirectPreDecAddressingMode(@NotNull M68kAddressRegisterIndirectPreDecAddressingMode o) {
visitAddressingMode(o);
// visitWithAddressRegisterIndirect(o);
}
public void visitAddressRegisterIndirectWithDisplacementNewAddressingMode(@NotNull M68kAddressRegisterIndirectWithDisplacementNewAddressingMode o) {
visitAddressingMode(o);
// visitWithAddressRegisterIndirect(o);
// visitWithDisplacement(o);
}
public void visitAddressRegisterIndirectWithDisplacementOldAddressingMode(@NotNull M68kAddressRegisterIndirectWithDisplacementOldAddressingMode o) {
visitAddressingMode(o);
// visitWithAddressRegisterIndirect(o);
// visitWithDisplacement(o);
}
public void visitAddressRegisterIndirectWithIndexNewAddressingMode(@NotNull M68kAddressRegisterIndirectWithIndexNewAddressingMode o) {
visitAddressingMode(o);
// visitWithAddressRegisterIndirect(o);
// visitWithDisplacement(o);
// visitWithIndexRegister(o);
}
public void visitAddressRegisterIndirectWithIndexOldAddressingMode(@NotNull M68kAddressRegisterIndirectWithIndexOldAddressingMode o) {
visitAddressingMode(o);
// visitWithAddressRegisterIndirect(o);
// visitWithDisplacement(o);
// visitWithIndexRegister(o);
}
public void visitAddressSize(@NotNull M68kAddressSize o) {
@ -116,18 +129,24 @@ public class M68kVisitor extends PsiElementVisitor {
public void visitProgramCounterIndirectWithDisplacementNewAddressingMode(@NotNull M68kProgramCounterIndirectWithDisplacementNewAddressingMode o) {
visitAddressingMode(o);
// visitWithDisplacement(o);
}
public void visitProgramCounterIndirectWithDisplacementOldAddressingMode(@NotNull M68kProgramCounterIndirectWithDisplacementOldAddressingMode o) {
visitAddressingMode(o);
// visitWithDisplacement(o);
}
public void visitProgramCounterIndirectWithIndexNewAddressingMode(@NotNull M68kProgramCounterIndirectWithIndexNewAddressingMode o) {
visitAddressingMode(o);
// visitWithDisplacement(o);
// visitWithIndexRegister(o);
}
public void visitProgramCounterIndirectWithIndexOldAddressingMode(@NotNull M68kProgramCounterIndirectWithIndexOldAddressingMode o) {
visitAddressingMode(o);
// visitWithDisplacement(o);
// visitWithIndexRegister(o);
}
public void visitProgramCounterReference(@NotNull M68kProgramCounterReference o) {
@ -142,6 +161,10 @@ public class M68kVisitor extends PsiElementVisitor {
visitAddressingMode(o);
}
public void visitRegisterRange(@NotNull M68kRegisterRange o) {
visitPsiElement(o);
}
public void visitSpecialRegister(@NotNull M68kSpecialRegister o) {
visitRegister(o);
}

View File

@ -35,7 +35,7 @@ public class M68kAddressRegisterIndirectWithDisplacementNewAddressingModeImpl ex
@Override
@NotNull
public M68kExpr getExpr() {
public M68kExpr getDisplacement() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kExpr.class));
}

View File

@ -35,7 +35,7 @@ public class M68kAddressRegisterIndirectWithDisplacementOldAddressingModeImpl ex
@Override
@NotNull
public M68kExpr getExpr() {
public M68kExpr getDisplacement() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kExpr.class));
}

View File

@ -33,20 +33,20 @@ public class M68kAddressRegisterIndirectWithIndexNewAddressingModeImpl extends M
@Override
@Nullable
public M68kDataWidth getDataWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
public M68kExpr getDisplacement() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
}
@Override
@NotNull
public M68kRegister getRegister() {
public M68kRegister getIndexRegister() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kRegister.class));
}
@Override
@Nullable
public M68kExpr getExpr() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
public M68kDataWidth getIndexWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
}
}

View File

@ -33,20 +33,20 @@ public class M68kAddressRegisterIndirectWithIndexOldAddressingModeImpl extends M
@Override
@Nullable
public M68kDataWidth getDataWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
public M68kExpr getDisplacement() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
}
@Override
@NotNull
public M68kRegister getRegister() {
public M68kRegister getIndexRegister() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kRegister.class));
}
@Override
@Nullable
public M68kExpr getExpr() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
public M68kDataWidth getIndexWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
}
}

View File

@ -28,7 +28,7 @@ public class M68kProgramCounterIndirectWithDisplacementNewAddressingModeImpl ext
@Override
@NotNull
public M68kExpr getExpr() {
public M68kExpr getDisplacement() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kExpr.class));
}

View File

@ -29,7 +29,7 @@ public class M68kProgramCounterIndirectWithDisplacementOldAddressingModeImpl ext
@Override
@Nullable
public M68kExpr getExpr() {
public M68kExpr getDisplacement() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
}

View File

@ -27,20 +27,20 @@ public class M68kProgramCounterIndirectWithIndexNewAddressingModeImpl extends M6
@Override
@Nullable
public M68kDataWidth getDataWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
public M68kExpr getDisplacement() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
}
@Override
@NotNull
public M68kRegister getRegister() {
public M68kRegister getIndexRegister() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kRegister.class));
}
@Override
@Nullable
public M68kExpr getExpr() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
public M68kDataWidth getIndexWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
}
}

View File

@ -27,20 +27,19 @@ public class M68kProgramCounterIndirectWithIndexOldAddressingModeImpl extends M6
@Override
@Nullable
public M68kDataWidth getDataWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
public M68kExpr getDisplacement() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
}
@Override
@NotNull
public M68kRegister getRegister() {
public M68kRegister getIndexRegister() {
return notNullChild(PsiTreeUtil.getChildOfType(this, M68kRegister.class));
}
@Override
@Nullable
public M68kExpr getExpr() {
return PsiTreeUtil.getChildOfType(this, M68kExpr.class);
public M68kDataWidth getIndexWidth() {
return PsiTreeUtil.getChildOfType(this, M68kDataWidth.class);
}
}

View File

@ -4,12 +4,12 @@ package de.platon42.intellij.plugins.m68k.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import de.platon42.intellij.plugins.m68k.psi.M68kRegister;
import de.platon42.intellij.plugins.m68k.psi.M68kRegisterListAddressingMode;
import de.platon42.intellij.plugins.m68k.psi.M68kVisitor;
import de.platon42.intellij.plugins.m68k.asm.Register;
import de.platon42.intellij.plugins.m68k.psi.*;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
public class M68kRegisterListAddressingModeImpl extends M68kAddressingModeImpl implements M68kRegisterListAddressingMode {
@ -34,4 +34,16 @@ public class M68kRegisterListAddressingModeImpl extends M68kAddressingModeImpl i
return PsiTreeUtil.getChildrenOfTypeAsList(this, M68kRegister.class);
}
@Override
@NotNull
public List<M68kRegisterRange> getRegisterRangeList() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, M68kRegisterRange.class);
}
@Override
@NotNull
public Set<Register> getRegisters() {
return M68kPsiImplUtil.getRegisters(this);
}
}

View File

@ -0,0 +1,52 @@
// 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.M68kRegister;
import de.platon42.intellij.plugins.m68k.psi.M68kRegisterRange;
import de.platon42.intellij.plugins.m68k.psi.M68kVisitor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class M68kRegisterRangeImpl extends ASTWrapperPsiElement implements M68kRegisterRange {
public M68kRegisterRangeImpl(@NotNull ASTNode node) {
super(node);
}
public void accept(@NotNull M68kVisitor visitor) {
visitor.visitRegisterRange(this);
}
@Override
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof M68kVisitor) accept((M68kVisitor) visitor);
else super.accept(visitor);
}
@Override
@NotNull
public List<M68kRegister> getRegisterList() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, M68kRegister.class);
}
@Override
@NotNull
public M68kRegister getStartRegister() {
List<M68kRegister> p1 = getRegisterList();
return p1.get(0);
}
@Override
@Nullable
public M68kRegister getEndRegister() {
List<M68kRegister> p1 = getRegisterList();
return p1.size() < 2 ? null : p1.get(1);
}
}

View File

@ -9,6 +9,31 @@ enum class Machine {
MC68060
}
enum class Register(val regname: String, val num: Int) {
D0("d0", 0),
D1("d1", 1),
D2("d2", 2),
D3("d3", 3),
D4("d4", 4),
D5("d5", 5),
D6("d6", 6),
D7("d7", 7),
A0("a0", 0),
A1("a1", 1),
A2("a2", 2),
A3("a3", 3),
A4("a4", 4),
A5("a5", 5),
A6("a6", 6),
A7("a7", 7);
companion object {
private val NAME_TO_REG_MAP = values().associateBy { it.regname }
fun getRegFromName(regname: String) = NAME_TO_REG_MAP[regname.lowercase()]!!
}
}
enum class AddressMode {
IMMEDIATE_DATA,
ADDRESS_REGISTER_INDIRECT_PRE_DEC,
@ -35,11 +60,63 @@ const val OP_SIZE_BWL = (OP_SIZE_B or OP_SIZE_W or OP_SIZE_L)
const val OP_SIZE_WL = (OP_SIZE_W or OP_SIZE_L)
const val OP_SIZE_SBW = (OP_SIZE_B or OP_SIZE_S or OP_SIZE_W)
const val RWM_READ_OPSIZE = 0x10
const val RWM_READ_B = 0x11
const val RWM_READ_W = 0x12
const val RWM_READ_L = 0x13
const val RWM_SET_OPSIZE = 0x20
const val RWM_SET_B = 0x21
const val RWM_SET_W = 0x22
const val RWM_SET_L = 0x23
const val RWM_MODIFY_OPSIZE = 0x30
const val RWM_MODIFY_B = 0x31
const val RWM_MODIFY_W = 0x32
const val RWM_MODIFY_L = 0x33
const val RWM_OP_MASK = 0xff
const val RWM_OP1_SHIFT = 0
const val RWM_OP2_SHIFT = 8
const val RWM_READ_OP1_OPSIZE = RWM_READ_OPSIZE shl RWM_OP1_SHIFT
const val RWM_READ_OP1_B = RWM_READ_B shl RWM_OP1_SHIFT
const val RWM_READ_OP1_W = RWM_READ_W shl RWM_OP1_SHIFT
const val RWM_READ_OP1_L = RWM_READ_L shl RWM_OP1_SHIFT
const val RWM_SET_OP1_OPSIZE = RWM_SET_OPSIZE shl RWM_OP1_SHIFT
const val RWM_SET_OP1_B = RWM_SET_B shl RWM_OP1_SHIFT
const val RWM_SET_OP1_W = RWM_SET_W shl RWM_OP1_SHIFT
const val RWM_SET_OP1_L = RWM_SET_L shl RWM_OP1_SHIFT
const val RWM_MODIFY_OP1_OPSIZE = RWM_MODIFY_OPSIZE shl RWM_OP1_SHIFT
const val RWM_MODIFY_OP1_B = RWM_MODIFY_B shl RWM_OP1_SHIFT
const val RWM_MODIFY_OP1_W = RWM_MODIFY_W shl RWM_OP1_SHIFT
const val RWM_MODIFY_OP1_L = RWM_MODIFY_L shl RWM_OP1_SHIFT
const val RWM_READ_OP2_OPSIZE = RWM_READ_OPSIZE shl RWM_OP2_SHIFT
const val RWM_READ_OP2_B = RWM_READ_B shl RWM_OP2_SHIFT
const val RWM_READ_OP2_W = RWM_READ_W shl RWM_OP2_SHIFT
const val RWM_READ_OP2_L = RWM_READ_L shl RWM_OP2_SHIFT
const val RWM_SET_OP2_OPSIZE = RWM_SET_OPSIZE shl RWM_OP2_SHIFT
const val RWM_SET_OP2_B = RWM_SET_B shl RWM_OP2_SHIFT
const val RWM_SET_OP2_W = RWM_SET_W shl RWM_OP2_SHIFT
const val RWM_SET_OP2_L = RWM_SET_L shl RWM_OP2_SHIFT
const val RWM_MODIFY_OP2_OPSIZE = RWM_MODIFY_OPSIZE shl RWM_OP2_SHIFT
const val RWM_MODIFY_OP2_B = RWM_MODIFY_B shl RWM_OP2_SHIFT
const val RWM_MODIFY_OP2_W = RWM_MODIFY_W shl RWM_OP2_SHIFT
const val RWM_MODIFY_OP2_L = RWM_MODIFY_L shl RWM_OP2_SHIFT
const val RWM_MODIFY_STACK = 0x10000
data class AllowedAdrMode(
val op1: Set<AddressMode>? = null,
val op2: Set<AddressMode>? = null,
val size: Int = OP_SIZE_BWL,
val specialReg: String? = null
val specialReg: String? = null,
val modInfo: Int = 0
)
data class IsaData(
@ -51,7 +128,7 @@ data class IsaData(
val id: String = mnemonic,
val isPrivileged: Boolean = false,
val hasOps: Boolean = true,
val modes: List<AllowedAdrMode> = listOf(AllowedAdrMode())
val modes: List<AllowedAdrMode> = listOf(AllowedAdrMode()),
)
object M68kIsa {
@ -131,21 +208,34 @@ object M68kIsa {
private val DREG_ONLY = setOf(AddressMode.DATA_REGISTER_DIRECT)
private val ADD_SUB_MODES = listOf(
AllowedAdrMode(ALL_EXCEPT_AREG, setOf(AddressMode.DATA_REGISTER_DIRECT)),
AllowedAdrMode(setOf(AddressMode.ADDRESS_REGISTER_DIRECT), setOf(AddressMode.DATA_REGISTER_DIRECT), OP_SIZE_WL),
AllowedAdrMode(setOf(AddressMode.DATA_REGISTER_DIRECT), INDIRECT_MODES),
AllowedAdrMode(ALL_EXCEPT_AREG, setOf(AddressMode.DATA_REGISTER_DIRECT), modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_DIRECT),
setOf(AddressMode.DATA_REGISTER_DIRECT),
OP_SIZE_WL,
modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE
),
AllowedAdrMode(setOf(AddressMode.DATA_REGISTER_DIRECT), INDIRECT_MODES, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
)
private val ASD_LSD_ROD_ROXD_MODES = listOf(
AllowedAdrMode(DREG_ONLY, DREG_ONLY),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY),
AllowedAdrMode(INDIRECT_MODES, null),
AllowedAdrMode(DREG_ONLY, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, modInfo = RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(INDIRECT_MODES, null, modInfo = RWM_MODIFY_OP1_OPSIZE),
)
private val BTST_BCHG_BCLR_BSET_MODES = listOf(
AllowedAdrMode(DREG_ONLY, ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, OP_SIZE_L),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, OP_SIZE_L),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), INDIRECT_MODES, OP_SIZE_B),
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),
AllowedAdrMode(DREG_ONLY, INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_READ_OP1_B or RWM_MODIFY_OP2_B),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, OP_SIZE_L, modInfo = RWM_MODIFY_OP2_L),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_MODIFY_OP2_B),
)
private val BTST_MODES = listOf(
AllowedAdrMode(DREG_ONLY, DREG_ONLY, OP_SIZE_L, modInfo = RWM_READ_OP1_B or RWM_READ_OP2_L),
AllowedAdrMode(DREG_ONLY, INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_READ_OP1_B or RWM_READ_OP2_B),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, OP_SIZE_L, modInfo = RWM_READ_OP2_L),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), INDIRECT_MODES, OP_SIZE_B, modInfo = RWM_READ_OP2_B),
)
private val conditionCodes =
@ -158,11 +248,11 @@ object M68kIsa {
// Data Movement Instructions
IsaData(
"move", "Move",
modes = listOf(AllowedAdrMode(ALL_68000_MODES, ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL))
modes = listOf(AllowedAdrMode(ALL_68000_MODES, ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_READ_OP1_OPSIZE or RWM_SET_OP2_OPSIZE))
),
IsaData(
"movea", "Move Address", altMnemonics = listOf("move"),
modes = listOf(AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL))
modes = listOf(AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL, modInfo = RWM_READ_OP1_OPSIZE or RWM_SET_OP2_L))
),
IsaData(
"movem", "Move Multiple Registers",
@ -176,7 +266,8 @@ object M68kIsa {
AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX,
AddressMode.ABSOLUTE_ADDRESS
),
OP_SIZE_WL
OP_SIZE_WL,
modInfo = RWM_READ_OP1_OPSIZE or RWM_SET_OP2_OPSIZE
),
AllowedAdrMode(
setOf(
@ -187,7 +278,8 @@ object M68kIsa {
AddressMode.ABSOLUTE_ADDRESS
),
setOf(AddressMode.REGISTER_LIST),
OP_SIZE_WL
OP_SIZE_WL,
modInfo = RWM_READ_OP1_OPSIZE or RWM_SET_OP2_OPSIZE
),
// according to Yann, specifying the registers as bitmask is also valid
AllowedAdrMode(
@ -199,7 +291,8 @@ object M68kIsa {
AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_INDEX,
AddressMode.ABSOLUTE_ADDRESS
),
OP_SIZE_WL
OP_SIZE_WL,
modInfo = RWM_SET_OP2_OPSIZE // Can't map immediate data to registers
),
AllowedAdrMode(
setOf(
@ -210,7 +303,8 @@ object M68kIsa {
AddressMode.ABSOLUTE_ADDRESS
),
setOf(AddressMode.IMMEDIATE_DATA),
OP_SIZE_WL
OP_SIZE_WL,
modInfo = RWM_READ_OP1_OPSIZE // Can't map immediate data to registers
),
)
),
@ -220,19 +314,21 @@ object M68kIsa {
AllowedAdrMode(
DREG_ONLY,
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT, AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT),
OP_SIZE_WL
OP_SIZE_WL,
modInfo = RWM_READ_OP1_OPSIZE
),
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT, AddressMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT),
DREG_ONLY,
OP_SIZE_WL
OP_SIZE_WL,
modInfo = RWM_SET_OP2_OPSIZE
)
)
),
IsaData(
"moveq", "Move Quick",
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, OP_SIZE_L))
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), DREG_ONLY, OP_SIZE_L, modInfo = RWM_SET_OP2_L))
),
IsaData(
@ -241,7 +337,8 @@ object M68kIsa {
AllowedAdrMode(
setOf(AddressMode.DATA_REGISTER_DIRECT, AddressMode.ADDRESS_REGISTER_DIRECT),
setOf(AddressMode.DATA_REGISTER_DIRECT, AddressMode.ADDRESS_REGISTER_DIRECT),
OP_SIZE_L
OP_SIZE_L,
modInfo = RWM_SET_OP1_L or RWM_SET_OP2_L
)
)
),
@ -258,7 +355,8 @@ object M68kIsa {
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX,
),
AREG_ONLY,
OP_SIZE_L
OP_SIZE_L,
modInfo = RWM_SET_OP2_L
)
)
),
@ -275,116 +373,165 @@ object M68kIsa {
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX,
),
null,
OP_SIZE_L
OP_SIZE_L,
modInfo = RWM_MODIFY_STACK
)
)
),
IsaData(
"link", "Link and Allocate",
modes = listOf(AllowedAdrMode(AREG_ONLY, setOf(AddressMode.IMMEDIATE_DATA), OP_SIZE_W))
modes = listOf(AllowedAdrMode(AREG_ONLY, setOf(AddressMode.IMMEDIATE_DATA), OP_SIZE_W, modInfo = RWM_SET_OP1_L or RWM_MODIFY_STACK))
),
IsaData(
"unlk", "Unlink",
modes = listOf(AllowedAdrMode(AREG_ONLY, null, OP_UNSIZED))
modes = listOf(AllowedAdrMode(AREG_ONLY, null, OP_UNSIZED, modInfo = RWM_SET_OP1_L or RWM_MODIFY_STACK))
),
// Integer Arithmetic Instructions
IsaData("add", "Add", modes = ADD_SUB_MODES),
IsaData("adda", "Add Address", altMnemonics = listOf("add"), modes = listOf(AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL))),
IsaData(
"adda", "Add Address", altMnemonics = listOf("add"),
modes = listOf(
AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_L),
)
),
IsaData(
"addi", "Add Immediate", altMnemonics = listOf("add"),
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL))
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_MODIFY_OP2_OPSIZE))
),
IsaData(
"addq", "Add Quick", modes = listOf(
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), AREG_ONLY, size = OP_SIZE_WL)
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), AREG_ONLY, size = OP_SIZE_WL, modInfo = RWM_MODIFY_OP2_L)
)
),
IsaData(
"addx", "Add with Extend",
modes = listOf(
AllowedAdrMode(DREG_ONLY, DREG_ONLY),
AllowedAdrMode(setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC), setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC))
AllowedAdrMode(DREG_ONLY, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE
)
)
),
IsaData("sub", "Subtract", modes = ADD_SUB_MODES),
IsaData("suba", "Subtract Address", altMnemonics = listOf("sub"), modes = listOf(AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL))),
IsaData(
"suba", "Subtract Address", altMnemonics = listOf("sub"),
modes = listOf(AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_L))
),
IsaData(
"subi", "Subtract Immediate", altMnemonics = listOf("sub"),
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL))
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_MODIFY_OP2_OPSIZE))
),
IsaData(
"subq", "Subtract Quick", modes = listOf(
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), AREG_ONLY, size = OP_SIZE_WL)
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), AREG_ONLY, size = OP_SIZE_WL, modInfo = RWM_MODIFY_OP2_L)
)
),
IsaData(
"subx", "Subtract with Extend",
modes = listOf(
AllowedAdrMode(DREG_ONLY, DREG_ONLY),
AllowedAdrMode(setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC), setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC))
AllowedAdrMode(DREG_ONLY, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE
)
)
),
IsaData("neg", "Negate", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null))),
IsaData("negx", "Negate with Extend", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null))),
IsaData("neg", "Negate", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, modInfo = RWM_MODIFY_OP1_OPSIZE))),
IsaData("negx", "Negate with Extend", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, modInfo = RWM_MODIFY_OP1_OPSIZE))),
IsaData("clr", "Clear", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null))),
IsaData("clr", "Clear", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, modInfo = RWM_SET_OP1_OPSIZE))),
IsaData(
"cmp", "Compare", modes = listOf(
AllowedAdrMode(ALL_EXCEPT_AREG, setOf(AddressMode.DATA_REGISTER_DIRECT)),
AllowedAdrMode(setOf(AddressMode.ADDRESS_REGISTER_DIRECT), setOf(AddressMode.DATA_REGISTER_DIRECT), OP_SIZE_WL),
AllowedAdrMode(ALL_EXCEPT_AREG, setOf(AddressMode.DATA_REGISTER_DIRECT), modInfo = RWM_READ_OP1_OPSIZE or RWM_READ_OP2_OPSIZE),
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_DIRECT),
setOf(AddressMode.DATA_REGISTER_DIRECT),
OP_SIZE_WL,
modInfo = RWM_READ_OP1_OPSIZE or RWM_READ_OP2_OPSIZE
),
)
),
IsaData("cmpa", "Compare Address", altMnemonics = listOf("cmp"), modes = listOf(AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL))),
IsaData(
"cmpa", "Compare Address", altMnemonics = listOf("cmp"),
modes = listOf(AllowedAdrMode(ALL_68000_MODES, AREG_ONLY, OP_SIZE_WL, modInfo = RWM_READ_OP1_OPSIZE or RWM_READ_OP2_L))
),
IsaData(
"cmpi", "Compare Immediate", altMnemonics = listOf("cmp"),
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_AND_IMMEDIATE))
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_AND_IMMEDIATE, modInfo = RWM_READ_OP2_OPSIZE))
),
IsaData(
"cmpm", "Compare Memory to Memory", altMnemonics = listOf("cmp"),
modes = listOf(AllowedAdrMode(setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_POST_INC), setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_POST_INC)))
modes = listOf(
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_POST_INC),
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_POST_INC),
modInfo = RWM_READ_OP1_OPSIZE or RWM_READ_OP2_OPSIZE
)
)
),
IsaData("muls", "Signed Multiply", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W))),
IsaData("mulu", "Unsigned Multiply", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W))),
IsaData("divs", "Signed Divide", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W))),
IsaData("divu", "Unsigned Divide", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W))),
IsaData(
"muls", "Signed Multiply",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W, modInfo = RWM_READ_OP1_W or RWM_MODIFY_OP2_L))
),
IsaData(
"mulu", "Unsigned Multiply",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W, modInfo = RWM_READ_OP1_W or RWM_MODIFY_OP2_L))
),
IsaData(
"divs", "Signed Divide",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W, modInfo = RWM_READ_OP1_L or RWM_MODIFY_OP2_L))
),
IsaData(
"divu", "Unsigned Divide",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W, modInfo = RWM_READ_OP1_L or RWM_MODIFY_OP2_L))
),
IsaData("ext", "Sign Extend", modes = listOf(AllowedAdrMode(DREG_ONLY, null, OP_SIZE_WL))),
IsaData("ext", "Sign Extend", modes = listOf(AllowedAdrMode(DREG_ONLY, null, OP_SIZE_WL, modInfo = RWM_MODIFY_OP1_OPSIZE))),
// Logical Instructions
IsaData(
"and", "Logical AND",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY), AllowedAdrMode(DREG_ONLY, INDIRECT_MODES))
modes = listOf(
AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(DREG_ONLY, INDIRECT_MODES, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE)
)
),
IsaData(
"andi", "Logical AND Immediate", altMnemonics = listOf("and"),
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL))
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_MODIFY_OP2_OPSIZE))
),
IsaData(
"eor", "Logical Exclusive-OR",
modes = listOf(AllowedAdrMode(DREG_ONLY, ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL))
modes = listOf(AllowedAdrMode(DREG_ONLY, ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE))
),
IsaData(
"eori", "Logical Exclusive-OR Immediate", altMnemonics = listOf("eor"),
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL))
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_MODIFY_OP2_OPSIZE))
),
IsaData(
"or", "Logical Inclusive-OR",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY), AllowedAdrMode(DREG_ONLY, INDIRECT_MODES))
modes = listOf(
AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(DREG_ONLY, INDIRECT_MODES, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE)
)
),
IsaData(
"ori", "Logical Inclusive-OR Immediate", altMnemonics = listOf("or"),
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL))
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, modInfo = RWM_MODIFY_OP2_OPSIZE))
),
IsaData(
"not", "Logical Complement",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null))
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, modInfo = RWM_MODIFY_OP1_OPSIZE))
),
// Shift and Rotate Instructions
@ -396,32 +543,42 @@ object M68kIsa {
IsaData("ror", "Rotate Right", modes = ASD_LSD_ROD_ROXD_MODES),
IsaData("roxl", "Rotate with Extend Left", modes = ASD_LSD_ROD_ROXD_MODES),
IsaData("roxr", "Rotate with Extend Right", modes = ASD_LSD_ROD_ROXD_MODES),
IsaData("swap", "Swap Register Words", modes = listOf(AllowedAdrMode(DREG_ONLY, null, OP_SIZE_W))),
IsaData("swap", "Swap Register Words", modes = listOf(AllowedAdrMode(DREG_ONLY, null, OP_SIZE_W, modInfo = RWM_MODIFY_OP1_L))),
// Bit Manipulation Instructions
IsaData("bchg", "Test Bit and Change", modes = BTST_BCHG_BCLR_BSET_MODES),
IsaData("bclr", "Test Bit and Clear", modes = BTST_BCHG_BCLR_BSET_MODES),
IsaData("bset", "Test Bit and Set", modes = BTST_BCHG_BCLR_BSET_MODES),
IsaData("btst", "Test Bit", modes = BTST_BCHG_BCLR_BSET_MODES),
IsaData("bchg", "Test Bit and Change", modes = BCHG_BCLR_BSET_MODES),
IsaData("bclr", "Test Bit and Clear", modes = BCHG_BCLR_BSET_MODES),
IsaData("bset", "Test Bit and Set", modes = BCHG_BCLR_BSET_MODES),
IsaData("btst", "Test Bit", modes = BTST_MODES),
// Binary-Coded Decimal Instructions
IsaData(
"abcd", "Add Decimal with Extend",
modes = listOf(
AllowedAdrMode(DREG_ONLY, DREG_ONLY, OP_SIZE_B),
AllowedAdrMode(setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC), setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC), OP_SIZE_B)
AllowedAdrMode(DREG_ONLY, DREG_ONLY, OP_SIZE_B, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
OP_SIZE_B,
modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE
)
)
),
IsaData(
"sbcd", "Subtract Decimal with Extend",
modes = listOf(
AllowedAdrMode(DREG_ONLY, DREG_ONLY, OP_SIZE_B),
AllowedAdrMode(setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC), setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC), OP_SIZE_B)
AllowedAdrMode(DREG_ONLY, DREG_ONLY, OP_SIZE_B, modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE),
AllowedAdrMode(
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
setOf(AddressMode.ADDRESS_REGISTER_INDIRECT_PRE_DEC),
OP_SIZE_B,
modInfo = RWM_READ_OP1_OPSIZE or RWM_MODIFY_OP2_OPSIZE
)
)
),
IsaData(
"nbcd", "Negate Decimal with Extend",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, OP_SIZE_B))
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, OP_SIZE_B, modInfo = RWM_MODIFY_OP1_OPSIZE))
),
// Program Control Instructions
@ -430,18 +587,22 @@ object M68kIsa {
modes = listOf(AllowedAdrMode(setOf(AddressMode.ABSOLUTE_ADDRESS), null, OP_SIZE_SBW))
),
IsaData("bra", "Branch", modes = listOf(AllowedAdrMode(setOf(AddressMode.ABSOLUTE_ADDRESS), null, OP_SIZE_SBW))),
IsaData("bsr", "Branch to Subroutine", modes = listOf(AllowedAdrMode(setOf(AddressMode.ABSOLUTE_ADDRESS), null, OP_SIZE_SBW))),
IsaData(
"bsr",
"Branch to Subroutine",
modes = listOf(AllowedAdrMode(setOf(AddressMode.ABSOLUTE_ADDRESS), null, OP_SIZE_SBW, modInfo = RWM_MODIFY_STACK))
),
IsaData(
"dbCC",
"Test Condition, Decrement, and Branch",
altMnemonics = listOf("dbra"),
conditionCodes = conditionCodes,
modes = listOf(AllowedAdrMode(DREG_ONLY, setOf(AddressMode.ABSOLUTE_ADDRESS), OP_SIZE_W))
modes = listOf(AllowedAdrMode(DREG_ONLY, setOf(AddressMode.ABSOLUTE_ADDRESS), OP_SIZE_W, modInfo = RWM_MODIFY_OP1_W))
),
IsaData(
"sCC", "Set Conditionally", conditionCodes = conditionCodes,
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, OP_SIZE_B))
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, OP_SIZE_B, modInfo = RWM_SET_OP2_B))
),
IsaData(
@ -470,16 +631,16 @@ object M68kIsa {
AddressMode.ABSOLUTE_ADDRESS,
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_DISPLACEMENT,
AddressMode.PROGRAM_COUNTER_INDIRECT_WITH_INDEX
), null, OP_UNSIZED
), null, OP_UNSIZED, modInfo = RWM_MODIFY_STACK
)
)
),
IsaData("nop", "No Operation", hasOps = false, modes = NO_OPS_UNSIZED),
IsaData("rtr", "Return and Restore", hasOps = false, modes = NO_OPS_UNSIZED),
IsaData("rts", "Return from Subroutine", hasOps = false, modes = NO_OPS_UNSIZED),
IsaData("rtr", "Return and Restore", hasOps = false, modes = listOf(AllowedAdrMode(size = OP_UNSIZED, modInfo = RWM_MODIFY_STACK))),
IsaData("rts", "Return from Subroutine", hasOps = false, modes = listOf(AllowedAdrMode(size = OP_UNSIZED, modInfo = RWM_MODIFY_STACK))),
IsaData("tst", "Test Operand", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null))),
IsaData("tst", "Test Operand", modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, null, modInfo = RWM_READ_OP1_OPSIZE))),
// System Control Instructions
IsaData(
@ -496,7 +657,15 @@ object M68kIsa {
),
IsaData(
"move", "Move from Status Register", id = "move from SR",
modes = listOf(AllowedAdrMode(setOf(AddressMode.SPECIAL_REGISTER_DIRECT), ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL, OP_SIZE_W, "sr"))
modes = listOf(
AllowedAdrMode(
setOf(AddressMode.SPECIAL_REGISTER_DIRECT),
ALL_EXCEPT_AREG_IMMEDIATE_AND_PC_REL,
OP_SIZE_W,
"sr",
modInfo = RWM_SET_OP2_W
)
)
),
IsaData(
"move", "Move to Status Register", id = "move to SR", isPrivileged = true,
@ -505,13 +674,16 @@ object M68kIsa {
IsaData(
"move", "Move User Stack Pointer", id = "move USP", isPrivileged = true,
modes = listOf(
AllowedAdrMode(setOf(AddressMode.SPECIAL_REGISTER_DIRECT), AREG_ONLY, OP_SIZE_L, "usp"),
AllowedAdrMode(AREG_ONLY, setOf(AddressMode.SPECIAL_REGISTER_DIRECT), OP_SIZE_L, "usp"),
AllowedAdrMode(setOf(AddressMode.SPECIAL_REGISTER_DIRECT), AREG_ONLY, OP_SIZE_L, "usp", modInfo = RWM_SET_OP2_L),
AllowedAdrMode(AREG_ONLY, setOf(AddressMode.SPECIAL_REGISTER_DIRECT), OP_SIZE_L, "usp", modInfo = RWM_READ_OP1_L),
)
),
IsaData("reset", "Reset External Devices", isPrivileged = true, hasOps = false, modes = NO_OPS_UNSIZED),
IsaData("rte", "Return from Exception", isPrivileged = true, hasOps = false, modes = NO_OPS_UNSIZED),
IsaData(
"rte", "Return from Exception", isPrivileged = true, hasOps = false,
modes = listOf(AllowedAdrMode(size = OP_UNSIZED, modInfo = RWM_MODIFY_STACK))
),
IsaData(
"stop", "Stop", isPrivileged = true,
modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), null, OP_UNSIZED))
@ -519,7 +691,7 @@ object M68kIsa {
IsaData(
"chk", "Check Register Against Bound",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W))
modes = listOf(AllowedAdrMode(ALL_EXCEPT_AREG, DREG_ONLY, OP_SIZE_W, modInfo = RWM_READ_OP1_W or RWM_READ_OP2_W))
),
IsaData("illegal", "Take Illegal Instruction Trap", hasOps = false, modes = NO_OPS_UNSIZED),
IsaData("trap", "Trap", modes = listOf(AllowedAdrMode(setOf(AddressMode.IMMEDIATE_DATA), null, OP_UNSIZED))),
@ -543,7 +715,10 @@ object M68kIsa {
),
// Multiprocessor Instructions
IsaData("tas", "Test Operand and Set", modes = listOf(AllowedAdrMode(ALL_EXCEPT_IMMEDIATE_AND_PC_REL, null, OP_SIZE_B)))
IsaData(
"tas", "Test Operand and Set",
modes = listOf(AllowedAdrMode(ALL_EXCEPT_IMMEDIATE_AND_PC_REL, null, OP_SIZE_B, modInfo = RWM_MODIFY_OP1_B))
)
)
val mnemonics =

View File

@ -255,20 +255,116 @@ AddressingMode ::= ImmediateData
SpecialRegisterDirectAddressingMode ::= SpecialRegister
DataRegisterDirectAddressingMode ::= DataRegister !(OP_MINUS|OP_AR_DIV)
AddressRegisterDirectAddressingMode ::= AddressRegister !(OP_MINUS|OP_AR_DIV)
AddressRegisterIndirectAddressingMode ::= ROUND_L AddressRegister ROUND_R !OP_PLUS
AddressRegisterIndirectPostIncAddressingMode ::= ROUND_L AddressRegister ROUND_R OP_PLUS
AddressRegisterIndirectPreDecAddressingMode ::= OP_MINUS ROUND_L AddressRegister ROUND_R
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 = [
"de.platon42.intellij.plugins.m68k.psi.M68kWithAddressRegisterIndirect"
"de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"
]
methods = [
displacement = "expr"
]
}
AddressRegisterIndirectWithDisplacementNewAddressingMode ::= ROUND_L expr SEPARATOR AddressRegister ROUND_R
{
implements = [
"de.platon42.intellij.plugins.m68k.psi.M68kWithAddressRegisterIndirect"
"de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"
]
methods = [
displacement = "expr"
]
}
AddressRegisterIndirectWithIndexOldAddressingMode ::= expr? ROUND_L AddressRegister SEPARATOR DataOrAddressRegister DataWidth? ROUND_R
{
implements = [
"de.platon42.intellij.plugins.m68k.psi.M68kWithAddressRegisterIndirect"
"de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"
"de.platon42.intellij.plugins.m68k.psi.M68kWithIndexRegister"
]
methods = [
displacement = "expr"
indexRegister = "Register"
indexWidth = "DataWidth"
]
}
AddressRegisterIndirectWithIndexNewAddressingMode ::= ROUND_L (expr SEPARATOR)? AddressRegister SEPARATOR DataOrAddressRegister DataWidth? ROUND_R
{
implements = [
"de.platon42.intellij.plugins.m68k.psi.M68kWithAddressRegisterIndirect"
"de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"
"de.platon42.intellij.plugins.m68k.psi.M68kWithIndexRegister"
]
methods = [
displacement = "expr"
indexRegister = "Register"
indexWidth = "DataWidth"
]
}
ProgramCounterIndirectWithDisplacementOldAddressingMode ::= (ROUND_L PC ROUND_R) | (expr ROUND_L PC ROUND_R)
{
implements = ["de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"]
methods = [
displacement = "expr"
]
}
ProgramCounterIndirectWithDisplacementNewAddressingMode ::= ROUND_L expr SEPARATOR PC ROUND_R
{
implements = ["de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"]
methods = [
displacement = "expr"
]
}
ProgramCounterIndirectWithIndexOldAddressingMode ::= expr? ROUND_L PC SEPARATOR DataOrAddressRegister DataWidth? ROUND_R
{
implements = [
"de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"
"de.platon42.intellij.plugins.m68k.psi.M68kWithIndexRegister"
]
methods = [
displacement = "expr"
indexRegister = "Register"
indexWidth = "DataWidth"
]
}
ProgramCounterIndirectWithIndexNewAddressingMode ::= ROUND_L (expr SEPARATOR)? PC SEPARATOR DataOrAddressRegister DataWidth? ROUND_R
{
implements = [
"de.platon42.intellij.plugins.m68k.psi.M68kWithDisplacement"
"de.platon42.intellij.plugins.m68k.psi.M68kWithIndexRegister"
]
methods = [
displacement = "expr"
indexRegister = "Register"
indexWidth = "DataWidth"
]
}
AbsoluteAddressAddressingMode ::= expr AddressSize? !ROUND_L
private RegisterRange ::= (DataOrAddressRegister OP_MINUS DataOrAddressRegister)
RegisterListAddressingMode ::= (DataOrAddressRegister|RegisterRange) ((OP_AR_DIV|OP_MINUS) (DataOrAddressRegister|RegisterRange))*
RegisterRange ::= (DataRegister OP_MINUS DataRegister) | (AddressRegister OP_MINUS AddressRegister) {
name = "register range"
methods = [
startRegister = "Register[0]"
endRegister = "Register[1]"
]
}
RegisterListAddressingMode ::= (RegisterRange|DataOrAddressRegister) (OP_AR_DIV (RegisterRange|DataOrAddressRegister))*
{
name = "register list"
methods = [ getRegisters ]
}
ImmediateData ::= HASH expr {
name = "immediate data"
extends = AddressingMode

View File

@ -1,6 +1,6 @@
package de.platon42.intellij.plugins.m68k.psi
import de.platon42.intellij.plugins.m68k.asm.AddressMode
import de.platon42.intellij.plugins.m68k.asm.*
object M68kAddressModeUtil {
fun getAddressModeForType(addressingMode: M68kAddressingMode?): AddressMode? {
@ -26,4 +26,32 @@ object M68kAddressModeUtil {
else -> throw IllegalArgumentException("Unknown addressing mode $addressingMode")
}
}
fun getReadWriteModifyRegisters(addressingMode: M68kAddressingMode?, rwm: Int): Set<Pair<Register, Int>> {
if (addressingMode == null) return emptySet()
return when (addressingMode) {
is M68kImmediateData -> emptySet()
is M68kAddressRegisterIndirectPostIncAddressingMode -> setOf(Register.getRegFromName(addressingMode.addressRegister.text) to RWM_MODIFY_OP1_L)
is M68kAddressRegisterIndirectPreDecAddressingMode -> setOf(Register.getRegFromName(addressingMode.addressRegister.text) to RWM_MODIFY_OP1_L)
is M68kWithAddressRegisterIndirect -> {
if (addressingMode is M68kWithIndexRegister) {
setOf(
Register.getRegFromName(addressingMode.addressRegister.text) to RWM_READ_OP1_L,
Register.getRegFromName(addressingMode.indexRegister.text) to if (addressingMode.hasLongWidth()) RWM_READ_OP1_L else RWM_READ_OP1_W
)
} else {
setOf(Register.getRegFromName(addressingMode.addressRegister.text) to RWM_READ_OP1_L)
}
}
is M68kWithIndexRegister -> setOf(Register.getRegFromName(addressingMode.indexRegister.text) to if (addressingMode.hasLongWidth()) RWM_READ_OP1_L else RWM_READ_OP1_W)
is M68kProgramCounterIndirectWithDisplacementNewAddressingMode -> emptySet()
is M68kProgramCounterIndirectWithDisplacementOldAddressingMode -> emptySet()
is M68kSpecialRegisterDirectAddressingMode -> emptySet()
is M68kDataRegisterDirectAddressingMode -> setOf(Register.getRegFromName(addressingMode.dataRegister.text) to rwm)
is M68kAddressRegisterDirectAddressingMode -> setOf(Register.getRegFromName(addressingMode.addressRegister.text) to rwm)
is M68kRegisterListAddressingMode -> addressingMode.registers.map { it to rwm }.toSet()
is M68kAbsoluteAddressAddressingMode -> emptySet()
else -> throw IllegalArgumentException("Unknown addressing mode $addressingMode")
}
}
}

View File

@ -113,4 +113,21 @@ object M68kPsiImplUtil {
".s" -> OP_SIZE_S
else -> throw IllegalArgumentException("Unknown op size ${element.text}")
}
// RegisterListAddressingMode
@JvmStatic
fun getRegisters(element: M68kRegisterListAddressingMode): Set<Register> {
val registers: MutableSet<Register> = HashSet()
element.registerList.forEach { registers.add(Register.getRegFromName(it.text)) }
element.registerRangeList.forEach {
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))
registers.add(startReg)
}
}
return registers
}
}

View File

@ -0,0 +1,6 @@
package de.platon42.intellij.plugins.m68k.psi
interface M68kWithAddressRegisterIndirect {
val addressRegister: M68kAddressRegister
}

View File

@ -0,0 +1,6 @@
package de.platon42.intellij.plugins.m68k.psi
interface M68kWithDisplacement {
val displacement: M68kExpr?
}

View File

@ -0,0 +1,12 @@
package de.platon42.intellij.plugins.m68k.psi
interface M68kWithIndexRegister {
val indexRegister: M68kRegister
val indexWidth: M68kDataWidth?
fun hasLongWidth(): Boolean {
return indexWidth?.text.equals(".l", ignoreCase = true)
}
}

View File

@ -1,8 +1,12 @@
package de.platon42.intellij.plugins.m68k.parser
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.jupiter.MyTestCase
import de.platon42.intellij.jupiter.ParsingTestExtension
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.m68k.asm.Register
import de.platon42.intellij.plugins.m68k.psi.M68kRegisterListAddressingMode
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
@TestDataSubPath("addressingmodes")
@ -85,7 +89,13 @@ internal class AddressingModesTest : AbstractParsingTest() {
@Test
internal fun movem_register_list(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
testGoodSyntax(testCase, " movem.l d0-d2/d4/a0-a2/a4,-(sp)\n")
testGoodSyntax(testCase, " movem.l d0-d2/d4/a0/a2-a3/a5,-(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.D4,
Register.A0, Register.A2, Register.A3, Register.A5,
)
}
@Test
@ -95,12 +105,17 @@ internal class AddressingModesTest : AbstractParsingTest() {
@Test
internal fun special_register_move(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
testGoodSyntax(testCase, " move.l usp,a0\n"
+ " move.l a5,usp\n")
testGoodSyntax(
testCase, " move.l usp,a0\n"
+ " move.l a5,usp\n"
)
}
@Test
internal fun complex_math_expression_in_displacement(@MyTestCase testCase: ParsingTestExtension.IParsingTestCase) {
testGoodSyntax(testCase, " move.l -(~(!!(+(1//~WIDTH^@123+3*4/2+(NARF%10|32!21))<<2)>>1)&$1f)(a0),(-(~(!!(+(1//~WIDTH^@123+3*4/2+(NARF%10|32!21))<<2)>>1)&\$1f),a0,d0.l)\n")
testGoodSyntax(
testCase,
" move.l -(~(!!(+(1//~WIDTH^@123+3*4/2+(NARF%10|32!21))<<2)>>1)&$1f)(a0),(-(~(!!(+(1//~WIDTH^@123+3*4/2+(NARF%10|32!21))<<2)>>1)&\$1f),a0,d0.l)\n"
)
}
}

View File

@ -8,23 +8,28 @@ Assembly File: a.asm
PsiElement(M68kTokenType.OPSIZE_L)('.l')
PsiWhiteSpace(' ')
M68kRegisterListAddressingModeImpl(REGISTER_LIST_ADDRESSING_MODE)
M68kDataRegisterImpl(DATA_REGISTER)
PsiElement(M68kTokenType.DREG)('d0')
PsiElement(M68kTokenType.OP_MINUS)('-')
M68kDataRegisterImpl(DATA_REGISTER)
PsiElement(M68kTokenType.DREG)('d2')
M68kRegisterRangeImpl(REGISTER_RANGE)
M68kDataRegisterImpl(DATA_REGISTER)
PsiElement(M68kTokenType.DREG)('d0')
PsiElement(M68kTokenType.OP_MINUS)('-')
M68kDataRegisterImpl(DATA_REGISTER)
PsiElement(M68kTokenType.DREG)('d2')
PsiElement(M68kTokenType.OP_AR_DIV)('/')
M68kDataRegisterImpl(DATA_REGISTER)
PsiElement(M68kTokenType.DREG)('d4')
PsiElement(M68kTokenType.OP_AR_DIV)('/')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a0')
PsiElement(M68kTokenType.OP_MINUS)('-')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a2')
PsiElement(M68kTokenType.OP_AR_DIV)('/')
M68kRegisterRangeImpl(REGISTER_RANGE)
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a2')
PsiElement(M68kTokenType.OP_MINUS)('-')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a3')
PsiElement(M68kTokenType.OP_AR_DIV)('/')
M68kAddressRegisterImpl(ADDRESS_REGISTER)
PsiElement(M68kTokenType.AREG)('a4')
PsiElement(M68kTokenType.AREG)('a5')
PsiElement(M68kTokenType.SEPARATOR)(',')
M68kAddressRegisterIndirectPreDecAddressingModeImpl(ADDRESS_REGISTER_INDIRECT_PRE_DEC_ADDRESSING_MODE)
PsiElement(M68kTokenType.OP_MINUS)('-')