Skip to content

All instructions lifted (Z80 arch)#10

Open
samrussell wants to merge 18 commits into
Vector35:masterfrom
samrussell:opcode_bundle_2
Open

All instructions lifted (Z80 arch)#10
samrussell wants to merge 18 commits into
Vector35:masterfrom
samrussell:opcode_bundle_2

Conversation

@samrussell

Copy link
Copy Markdown
Contributor

No description provided.

bugfix: add perform_get_address_size(self) to ColecoView
feature: lifted RST, conditional CALL, CPL, NEG, RES, SET
Added opcodes DI EI HALT IM OUTI OUTD OTIR OTDR SCF SLA SRL
Added extra flag sets on SRA
Implemented overflow flag for ADC (copied from SBB implementation)
Goal is to pretend the F part of the AF register doesn't exist. Pushing
and popping in single bytes tidies the POP slightly, and moved to using
il.flag_bit() which gives same results as PUSHFQ/POPFQ in the built-in
x64 lifter
@plafosse

plafosse commented Mar 2, 2024

Copy link
Copy Markdown
Member

Very cool! Thanks for the PR!

@xusheng6

xusheng6 commented Mar 4, 2024

Copy link
Copy Markdown
Member

I will be reviewing this

@xusheng6
xusheng6 self-requested a review March 4, 2024 14:40
@xusheng6
xusheng6 requested review from galenbwill and removed request for xusheng6 March 15, 2024 08:28
@plafosse plafosse added this to the Elysium milestone Mar 20, 2024
@galenbwill galenbwill changed the title All instructions lifted All instructions lifted (Z80 arch) Apr 24, 2024
@galenbwill galenbwill removed this from the Elysium milestone Jun 25, 2024
@samrussell

Copy link
Copy Markdown
Contributor Author

Hi guys, any chance someone could take a look at this? I can break it into smaller pieces if that makes life easier

@galenbwill

Copy link
Copy Markdown

I will prioritize reviewing it.

@psifertex
psifertex removed the request for review from galenbwill July 16, 2026 21:54
@psifertex

Copy link
Copy Markdown
Member

Dang, I'm sorry we let this one lapse. We weren't tracking it on our main tasking board. I'm moving it there so we don't lose it again. My apologies.

@psifertex psifertex added this to the Krypton milestone Jul 16, 2026
@xusheng6 xusheng6 self-assigned this Jul 16, 2026
@samrussell

Copy link
Copy Markdown
Contributor Author

Better late than never :)

@xusheng6
xusheng6 self-requested a review July 17, 2026 16:32

@xusheng6 xusheng6 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I found a few issues in the code. Once these are fixed, it should be good to go.

Sorry again for our late resoonse. I will respond promptly once you get these addressed!

Comment thread Z80IL.py
temp0 = LLIL_TEMP(0)
il.append(il.intrinsic([ILRegister(il.arch, temp0)], "in", [il.reg(1, 'C')]))
# save to (HL)
il.append(il.store(1, il.reg(2, 'HL'), temp0))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be il.reg(1, temp0) instead of just temp0. temp0 is the index of the temp register, using it directly does not refer to the register. This also happens on line 757, 773, 792

Comment thread Z80IL.py
tmp = il.sub(2, il.reg(2, 'BC'), il.const(2, 1))
il.append(il.set_reg(2, 'BC', tmp))
il.append(il.set_flag('pv', il.compare_not_equal(2, il.reg(2, 'BC'), il.const(2, 0))))
il.append(il.if_expr(il.or_expr(1, il.flag('z'), il.neg_expr(1, il.flag('pv'))), label_done, label_loop))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

neg_expr does arithemetic negation, not logical, so I believe the condition is wrong. Same pattern on line 544

Comment thread Z80IL.py
# if lower nybble > 9 OR H flag set then we diff by 0x06
label_add_6 = LowLevelILLabel()
label_dont_add_6 = LowLevelILLabel()
lower_nybble = il.xor_expr(1, il.const(1, 0x0F), il.reg(1, 'A'))

@xusheng6 xusheng6 Jul 17, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this should be an and instead of xor, in order to extract the bits

Also as a comment, for instructions like DAA, we usually (e.g., for x86) just lift it as an intrinsic rather than spelling out the entire computation. I am not against your doing it like this since z80 is simple enough, so it is practical to do it for all instructions, but I am a bit worried that it hurts readability than helps it. After all this is merely a suggestion, you do not have to change anything

Comment thread Z80IL.py
Comment on lines +986 to +991
il.append(il.set_flag('s', il.test_bit(1, temp0, il.const(1, 1<<7))))
il.append(il.set_flag('z', il.test_bit(1, temp0, il.const(1, 1<<6))))
il.append(il.set_flag('h', il.test_bit(1, temp0, il.const(1, 1<<4))))
il.append(il.set_flag('pv', il.test_bit(1, temp0, il.const(1, 1<<2))))
il.append(il.set_flag('n', il.test_bit(1, temp0, il.const(1, 1<<1))))
il.append(il.set_flag('c', il.test_bit(1, temp0, il.const(1, 1))))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

il.test_bit tests the bit at the given index, there is no need to do 1<<7 -- just pass in il.const(1, 7). Same pattern at line 681

Comment thread Z80IL.py
# decrement B
tmp = il.reg(1, 'B')
tmp = il.add(1, tmp, il.const(1,-1))
tmp = il.sub(1, tmp, il.const(1, 1), 'z')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This will incorrectly update the value of the z flag, which DJNZ does not modify. You could try something like this:

  result = il.sub(1, il.reg(1, 'B'), il.const(1, 1))
  il.append(il.set_reg(1, 'B', result))

  condition = il.compare_not_equal(
      1,
      il.reg(1, 'B'),
      il.const(1, 0)
  )
  il.append(il.if_expr(condition, label_loop, label_continue))

Comment thread Z80IL.py
# BC = BC - 1
tmp = il.sub(2, il.reg(2, 'BC'), il.const(2, 1))
il.append(il.set_reg(2, 'BC', tmp))
il.append(il.set_flag('pv', il.compare_equal(2, il.reg(2, 'BC'), il.const(2, 0))))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the condition here is inverted -- it should be il.compare_not_equal

@xusheng6 xusheng6 removed their assignment Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants