Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 30 |
Nodes: | 6 (1 / 5) |
Uptime: | 66:30:19 |
Calls: | 414 |
Calls today: | 1 |
Files: | 1,015 |
Messages: | 94,229 |
Posted today: | 1 |
One thought I had a while ago using a similar technique to glyph's was
to place constants at the beginning or the end of a cache line. Then the immediate base register is not needed. The relative offsets would be in
terms of the current cache line. It has a couple of drawbacks though,
one being the need to branch around the constant data; could be done by carefully maintaining the next fetch address. Another drawback is the
code is repositionable only at cache-line boundaries. Might make
assembling / linking code interesting.
On Sun, 9 Mar 2025 12:03:22 +0000, Robert Finch wrote:
One thought I had a while ago using a similar technique to glyph's was
to place constants at the beginning or the end of a cache line. Then the
immediate base register is not needed. The relative offsets would be in
terms of the current cache line. It has a couple of drawbacks though,
one being the need to branch around the constant data; could be done by
carefully maintaining the next fetch address. Another drawback is the
code is repositionable only at cache-line boundaries. Might make
assembling / linking code interesting.
If you put the constants at the end of the cache line, you will have
accessed the constants while decoding the instructions and you can
figure out when to jump to the next cache line without branching.
Robert Finch <robfi680@gmail.com> schrieb:
I think splitting the code and constant into separate streams requires
another port(s) on the I$. The port may already be present if
jump-through-table, JTT, is supported.
There is also the problem of additional cache (page, ...) misses with
the instruction stream. Maybe an extra "constant data" cache?
That would depend on how far the extra data is from the code.
But branches are going to be more expensive because it is not
only the PC that needs to changed, but also the data pointer.
Thinking about this a bit more... conceptually, this is not so far
off from the /360 base pointer addressing mode, but with the base
pointer implied instead of explicit.
I guess that the constant tables for a subroutine would be placed either
before or after a subroutine.
Like what was usually done for the /360, I believe.
But much more "fun" could be had if the base pointer was supplied
by the caller. Want a routine that does something different,
just call it with a different constant stream for instructions.
(OK, you could also pass an argument, but that would offer less
possibilities for quasi self-modifying code).
On 2025-03-08 9:21 a.m., Thomas Koenig wrote:
There was a recent post to the gcc mailing list which showed
interesting concept of dealing with large constants in an ISA:
Splitting a the instruction and constant stream. It can be found
at https://github.com/michaeljclark/glyph/ , and is named "glyph".
I think the problem the author is trying to solve is better addressed by
My 66000 (and I would absolutely _hate_ to write an assembler for it).
Still, I thought it worth mentioning.
I think it is better to use a constant prefix / postfix instruction to
encode larger constants in the instruction stream. Or use a wider
instruction format. In Q+ constant postfixes can be used to override a register spec, allowing immediate constants to be used with many more instructions.
Robert Finch wrote:
On 2025-03-08 9:21 a.m., Thomas Koenig wrote:
There was a recent post to the gcc mailing list which showed
interesting concept of dealing with large constants in an ISA:
Splitting a the instruction and constant stream. It can be found
at https://github.com/michaeljclark/glyph/ , and is named "glyph".
I think the problem the author is trying to solve is better addressed by >>> My 66000 (and I would absolutely _hate_ to write an assembler for it).
Still, I thought it worth mentioning.
I think it is better to use a constant prefix / postfix instruction to
encode larger constants in the instruction stream. Or use a wider
instruction format. In Q+ constant postfixes can be used to override a
register spec, allowing immediate constants to be used with many more
instructions.
Yes a kind of prefix instruction that say "here comes an immediate
value"
and loads a 2, 4, or 8 byte immediate with all the sign or zero extend options into a special constant register in the Decoder and marks it
valid.
The next instruction just says add immediate "ADDI rd, rs" and it
implies
the constant it just stashed.
That relieves the consumer opcodes from having to encode all the
different variable immediate formats.
It could easily extend to multiple immediate prefix instructions so
one can have instructions like store immediate STD [rd+imm1], imm2
by just adding a second constant register to the Decoder.
The only complication I can see is if the instruction producer-consumer
pair straddle pages and their is a page fault on the second.
I wouldn't want to have to save the stashed constant as "thread context"
so it should roll back to the start of the immediate instruction.
In which case the faulting RIP is the first instruction and the
faulting address is someplace in the second.
MitchAlsup1 <mitchalsup@aol.com> schrieb:
On Sun, 9 Mar 2025 12:03:22 +0000, Robert Finch wrote:
One thought I had a while ago using a similar technique to glyph's was
to place constants at the beginning or the end of a cache line. Then the >>> immediate base register is not needed. The relative offsets would be in
terms of the current cache line. It has a couple of drawbacks though,
one being the need to branch around the constant data; could be done by
carefully maintaining the next fetch address. Another drawback is the
code is repositionable only at cache-line boundaries. Might make
assembling / linking code interesting.
If you put the constants at the end of the cache line, you will have
accessed the constants while decoding the instructions and you can
figure out when to jump to the next cache line without branching.
Did I mention I would not like to write an assembler for that? :-)
On Sun, 9 Mar 2025 21:02:44 +0000, EricP wrote:
Robert Finch wrote:
On 2025-03-08 9:21 a.m., Thomas Koenig wrote:
There was a recent post to the gcc mailing list which showed
interesting concept of dealing with large constants in an ISA:
Splitting a the instruction and constant stream. It can be found
at https://github.com/michaeljclark/glyph/ , and is named "glyph".
I think the problem the author is trying to solve is better
addressed by
My 66000 (and I would absolutely _hate_ to write an assembler for it). >>>> Still, I thought it worth mentioning.
I think it is better to use a constant prefix / postfix instruction to
encode larger constants in the instruction stream. Or use a wider
instruction format. In Q+ constant postfixes can be used to override a
register spec, allowing immediate constants to be used with many more
instructions.
Yes a kind of prefix instruction that say "here comes an immediate
value"
and loads a 2, 4, or 8 byte immediate with all the sign or zero extend
options into a special constant register in the Decoder and marks it
valid.
The next instruction just says add immediate "ADDI rd, rs" and it
implies
the constant it just stashed.
That relieves the consumer opcodes from having to encode all the
different variable immediate formats.
It could easily extend to multiple immediate prefix instructions so
one can have instructions like store immediate STD [rd+imm1], imm2
by just adding a second constant register to the Decoder.
The only complication I can see is if the instruction producer-consumer
pair straddle pages and their is a page fault on the second.
I wouldn't want to have to save the stashed constant as "thread context"
so it should roll back to the start of the immediate instruction.
Execute the instruction and the (preceding) constant as a single
instruction, so any fault leaves IP pointing at the constant.
In which case the faulting RIP is the first instruction and the
faulting address is someplace in the second.
On 2025-03-22 11:04 a.m., Thomas Koenig wrote:
Marcus <m.delete@this.bitsnbites.eu> schrieb:
Then we have the page-crossing issue. Is it better to force the
compiler/assembler to align such instructions so that they never cross
page boundaries?
Power 10 chose to do so; actually, larger instructions cannot
cross a (likely) Cache line size there. According to the Power
ISA Version 3.1, section 1.6:
"Prefixed instructions do not cross 64-byte instruction address
boundaries. When a prefixed instruction crosses a 64-byte boundary,
the system alignment error handler is invoked."
In the latest test project, the LB650 similar to a PowerPC, large
constants are encoded at the end of the cache line. So, there is a
similar issue of code running into the constant area.
I have the assembler moving the code that overlaps to the next cache line.
It is confusing to look at listing files, as there are constants output inline with the code. Makes it look like the code should not work. How
does it know where to go for the next instruction? Is the question that
comes to mind.
For now, the hardware decoder takes the cheezy approach of marking instructions fetched in the constant area as invalid. The constant area
gets fetched and loaded into the pipeline, but as NOPs.
It is quite a trick getting the assembler to place constants at the end
of the cache line and generate references to the constants. It is
interesting because I have *constants* being relocated by the assembler
/ linker. Normally there would not be a relocation associated with a constant. A relocation reference to the constant is spit out by the assembler, and the linker updates the index to the constant in the code.
It does not quite work yet. Constants are placed and code is moved, but
the linked program does not have the correct references yet.
Experimental, but looking like things will work.
In the latest test project, the LB650 similar to a PowerPC, large
constants are encoded at the end of the cache line. So, there is a
similar issue of code running into the constant area.
Den 2025-03-09 kl. 22:19, skrev MitchAlsup1:
On Sun, 9 Mar 2025 21:02:44 +0000, EricP wrote:
Robert Finch wrote:
On 2025-03-08 9:21 a.m., Thomas Koenig wrote:
There was a recent post to the gcc mailing list which showed
interesting concept of dealing with large constants in an ISA:
Splitting a the instruction and constant stream. It can be found
at https://github.com/michaeljclark/glyph/ , and is named "glyph".
I think the problem the author is trying to solve is better
addressed by
My 66000 (and I would absolutely _hate_ to write an assembler for it). >>>>> Still, I thought it worth mentioning.
I think it is better to use a constant prefix / postfix instruction to >>>> encode larger constants in the instruction stream. Or use a wider
instruction format. In Q+ constant postfixes can be used to override a >>>> register spec, allowing immediate constants to be used with many more
instructions.
Yes a kind of prefix instruction that say "here comes an immediate
value"
and loads a 2, 4, or 8 byte immediate with all the sign or zero extend
options into a special constant register in the Decoder and marks it
valid.
The next instruction just says add immediate "ADDI rd, rs" and it
implies
the constant it just stashed.
That relieves the consumer opcodes from having to encode all the
different variable immediate formats.
It could easily extend to multiple immediate prefix instructions so
one can have instructions like store immediate STD [rd+imm1], imm2
by just adding a second constant register to the Decoder.
The only complication I can see is if the instruction producer-consumer
pair straddle pages and their is a page fault on the second.
I wouldn't want to have to save the stashed constant as "thread context" >>> so it should roll back to the start of the immediate instruction.
Execute the instruction and the (preceding) constant as a single
instruction, so any fault leaves IP pointing at the constant.
Then we have the page-crossing issue. Is it better to force the compiler/assembler to align such instructions so that they never cross
page boundaries?
In which case the faulting RIP is the first instruction and the
faulting address is someplace in the second.
Den 2025-03-23 kl. 04:06, skrev Robert Finch:
On 2025-03-22 11:04 a.m., Thomas Koenig wrote:
Marcus <m.delete@this.bitsnbites.eu> schrieb:
Then we have the page-crossing issue. Is it better to force the
compiler/assembler to align such instructions so that they never cross >>>> page boundaries?
Power 10 chose to do so; actually, larger instructions cannot
cross a (likely) Cache line size there. According to the Power
ISA Version 3.1, section 1.6:
"Prefixed instructions do not cross 64-byte instruction address
boundaries. When a prefixed instruction crosses a 64-byte boundary,
the system alignment error handler is invoked."
In the latest test project, the LB650 similar to a PowerPC, large
constants are encoded at the end of the cache line. So, there is a
similar issue of code running into the constant area.
I have the assembler moving the code that overlaps to the next cache
line.
It is confusing to look at listing files, as there are constants output
inline with the code. Makes it look like the code should not work. How
does it know where to go for the next instruction? Is the question that
comes to mind.
For now, the hardware decoder takes the cheezy approach of marking
instructions fetched in the constant area as invalid. The constant area
gets fetched and loaded into the pipeline, but as NOPs.
It is quite a trick getting the assembler to place constants at the end
of the cache line and generate references to the constants. It is
interesting because I have *constants* being relocated by the assembler
/ linker. Normally there would not be a relocation associated with a
constant. A relocation reference to the constant is spit out by the
assembler, and the linker updates the index to the constant in the code.
It does not quite work yet. Constants are placed and code is moved, but
the linked program does not have the correct references yet.
Experimental, but looking like things will work.
Although I have not tried any of these techniques, here are my thoughts.
Why not always place the constant next to (right after) the instruction
that references it, instead of at an offset within the cache line?
The effect should be very similar, but now you have a simpler offset
(it's always zero) and you eliminate the problem with having to keep
track of where the constants are in order to prevent the PC/IP from
running into the constant area.
On 2025-03-23 8:12 a.m., Marcus wrote:
Den 2025-03-23 kl. 04:06, skrev Robert Finch:
On 2025-03-22 11:04 a.m., Thomas Koenig wrote:
Marcus <m.delete@this.bitsnbites.eu> schrieb:
That is a very good idea. It is the same thing almost as using aIt does not quite work yet. Constants are placed and code is moved,
but the linked program does not have the correct references yet.
Experimental, but looking like things will work.
Although I have not tried any of these techniques, here are my thoughts.
Why not always place the constant next to (right after) the instruction
that references it, instead of at an offset within the cache line?
variable length instruction.
LB650 uses a smaller constant packet (16-bits) than the instruction. So, instructions would need to be able to be aligned at 16-bit boundaries.
LB650 instruction are fixed 32-bit. There is also the possibility of
sharing the same constants, although slim.
The effect should be very similar, but now you have a simpler offsetI wish I had thought of that last night. But I have coded things now.
(it's always zero) and you eliminate the problem with having to keep
track of where the constants are in order to prevent the PC/IP from
running into the constant area.
Got the compiler / assembler going. The listings are a few percent
shorter than the PowerPC. It may be due to bugs yet. I think the
difference may be the PowerPC burns up bits using pairs of instructions
for high/low halves of the constant.
The vbcc compiler for the PowerPC was modified.
On 2025-03-23 8:12 a.m., Marcus wrote:
Why not always place the constant next to (right after) the instructionThat is a very good idea. It is the same thing almost as using a
that references it, instead of at an offset within the cache line?
variable length instruction.