sy2002 / QNICE-FPGA

QNICE-FPGA is a 16-bit computer system for recreational programming built as a fully-fledged System-on-a-Chip in portable VHDL.
http://qnice-fpga.com
Other
69 stars 15 forks source link

Update cpu_test.asm #180

Closed MJoergen closed 3 years ago

MJoergen commented 3 years ago

Add test of conditional branches and subroutine calls together with the different addressing modes.

E.g. the following instructions:

RBRA R0, Z
RBRA @R0, Z
RBRA @R0++, Z
RBRA @--R0, Z

and the same with RSUB.

And test with both R0, R8, R13, and R15

sy2002 commented 3 years ago

@MJoergen And with R15, too, as R15 needs to be treated in a special way?

MJoergen commented 3 years ago

@MJoergen And with R15, too, as R15 needs to be treated in a special way?

Thank you. Updated.

MJoergen commented 3 years ago

I've now added test of ABRA combined with different addressing modes of R0. And the emulator has been updated too.

I'm now thinking about how to expand the test to include RBRA, but that is a bit trickier, because the assembler does not support calculation. Ideally, I would like to write something like:

MOVE *+2, R0

where * gets interpreted as the current location in memory. I had a brief look at the assembler, but this seems like a non-trivial addition.

MJoergen commented 3 years ago

I've decided to skip testing RBRA with registers, because the assembler does not support this nicely, so the programmer will probably not use this feature. If at a later stage the assembler is expanded with calculations, then we should re-open this issue.

bernd-ulmann commented 3 years ago

Do we need something like PC relative addressing in the assembler? In what case would this be helpful since one can (and as I think should :-) ) always define a label at the destination or am I missing something here?

MJoergen commented 3 years ago

Do we need something like PC relative addressing in the assembler? In what case would this be helpful since one can (and as I think should :-) ) always define a label at the destination or am I missing something here?

Well, I agree!

But I'm trying to test the relative branches (RBRA and RSUB) to an indirect address. I know relative branches are used when making relocatable code, but that is usually with a constant destination (which is calculated automatically by the assembler). When do we use indirect relative addressing?

I'm trying to come up with a use case for e.g. RBRA R0, 1. In order to fill in an appropriate value in R0 I need some address calculation. Something like the below:

MOVE  <label>-*, R0
RBRA  R0, 1
...
label: 

Here <label>-* is a compile-time constant.

But this example is flawed, because the value in R0 is not correct, because * refers to the address after the MOVE instruction, but should instead refer to the address after the RBRA instruction.

So perhaps something like this instead:

MOVE  <label>-<source>, R0
RBRA  R0, 1
source:
...
label: 

Does this even make sense?

Here is a variation over the same theme:

MOVE  <pointer>, R0
RBRA  @R0, 1
source:
...
label:
...
pointer: .DW <label>-<source>

In this last example I'm essentially trying to build a jump-table that is relocatable.

bernd-ulmann commented 3 years ago

I, too, don't see a real world use case for a relative branch/subroutine call with an indirect address. :-)