Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SH4 support #114

Merged
merged 5 commits into from
Jun 27, 2023
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# asm-differ

Nice differ for assembly code. Currently supports MIPS, PPC, AArch64, ARM32, and SH2; should be easy to hack to support other instruction sets.
Nice differ for assembly code. Currently supports MIPS, PPC, AArch64, ARM32, SH2, and SH4; should be easy to hack to support other instruction sets.

![](screenshot.png)

34 changes: 31 additions & 3 deletions diff.py
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ class DiffMode(enum.Enum):
argcomplete = None

parser = argparse.ArgumentParser(
description="Diff MIPS, PPC, AArch64, ARM32, or SH2 assembly."
description="Diff MIPS, PPC, AArch64, ARM32, SH2, or SH4 assembly."
)

start_argument = parser.add_argument(
@@ -560,6 +560,7 @@ def get_objdump_executable(objdump_executable: Optional[str]) -> str:
"mips64-elf-objdump",
"mips-elf-objdump",
"sh-elf-objdump",
"sh4-linux-gnu-objdump",
]
for objdump_cand in objdump_candidates:
try:
@@ -1825,6 +1826,17 @@ def is_end_of_function(self, mnemonic: str, args: str) -> bool:
return mnemonic == "rts"


class AsmProcessorSH4(AsmProcessor):
def __init__(self, config: Config) -> None:
super().__init__(config)

def process_reloc(self, row: str, prev: str) -> Tuple[str, Optional[str]]:
return prev, None

def is_end_of_function(self, mnemonic: str, args: str) -> bool:
return mnemonic == "rts"


@dataclass
class ArchSettings:
name: str
@@ -2177,6 +2189,20 @@ class ArchSettings:
proc=AsmProcessorSH2,
)

SH4_SETTINGS = replace(
SH2_SETTINGS,
name="sh4",
# - fr0-fr15, dr0-dr14, xd0-xd14, fv0-fv12 FP registers
# dr/xd registers can only be even-numbered, and fv registers can only be a multiple of 4
re_reg=re.compile(
r"r1[0-5]|r[0-9]|fr1[0-5]|fr[0-9]|dr[02468]|dr1[024]|xd[02468]|xd1[024]|fv[048]|fv12"
),
arch_flags=["-m", "sh4"],
proc=AsmProcessorSH4,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should use AsmProcessorSH2 instead of defining a new one? I don't know enough about the arch to say whether there are any cases where we have to treat them differently, so I'll let you decide

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK there aren't (and won't be) any differences between the two AsmProcessors -- I'll remove AsmProcessorSH4 then

)

SH4EL_SETTINGS = replace(SH4_SETTINGS, name="sh4el", big_endian=False)

ARCH_SETTINGS = [
MIPS_SETTINGS,
MIPSEL_SETTINGS,
@@ -2187,15 +2213,17 @@ class ArchSettings:
PPC_SETTINGS,
I686_SETTINGS,
SH2_SETTINGS,
SH4_SETTINGS,
SH4EL_SETTINGS,
]


def hexify_int(row: str, pat: Match[str], arch: ArchSettings) -> str:
full = pat.group(0)

# sh2 only has 8-bit immediates, just convert them uniformly without
# sh2/sh4 only has 8-bit immediates, just convert them uniformly without
# any -hex stuff
if arch.name == "sh2":
if arch.name == "sh2" or arch.name == "sh4" or arch.name == "sh4el":
return hex(int(full) & 0xFF)

if len(full) <= 1: