I was not happy that when I did not use a block prefix, I had to omit the Load Medium and Store Medium instructions from the basic load/store instructions.
I searched for available opcode space.--- Synchronet 3.21f-Linux NewsLink 1.2
I found a little; enough for the _other_ block prefixes. But not a full
1/16 of the opcode space which is what the Type I header needed. Where did
I find it? In the opcodes for operate instructions which the 15-bit paired short instructions don't use.
So I thought that perhaps I could shrink the requirements of the Type I header. If, by making use of the fact that 10 (start of 32-bit or longer instruction) can only be followed by 11 (not the start of an instruction), then maybe I could replace four consecutive two-bit prefixes by one seven- bit prefix.
But alas, this fact only reduced the possibilities to 81 + 27 + 27 + 1, which is 136, which is greater than 128.
However, if I made use of the fact that I would know if the preceding 16-
bit zone began a 32-bit instruction, and added certain other restrictions
on the allowed combinations - by insisting that all pseudo-immediates be tidily put at the end of the block - I thought I was able to squeeze it in.
This may be a step too far, so I've saved everything if I need to go back.
John Savard
quadi <[email protected]d> posted:
I was not happy that when I did not use a block prefix, I had to omit
the Load Medium and Store Medium instructions from the basic load/store
instructions.
Is LD Medium obtaining a sooth sayer from memory?
Is ST Medium putting a sooth sayer back in memory?
How do you know a sooth sayer fits in 2^(3+n) bytes???
On Wed, 22 Apr 2026 18:15:17 +0000, MitchAlsup wrote:
quadi <[email protected]d> posted:
I was not happy that when I did not use a block prefix, I had to omit
the Load Medium and Store Medium instructions from the basic load/store
instructions.
Is LD Medium obtaining a sooth sayer from memory?
Is ST Medium putting a sooth sayer back in memory?
How do you know a sooth sayer fits in 2^(3+n) bytes???
No, I am not referring to one who channels the spirits of the dead.
Instead, the Medium data type refers to 48-bit floating-point values; although not part of the IEEE 754 standard, they follow the pattern of the types defined in it. They offer a precision just above 11 decimal digits,
and an exponent range that exceeds 10 to plus or minus 99, thus
approximating the numbers pocket calculators make available.
On 4/22/2026 10:35 PM, quadi wrote:
On Wed, 22 Apr 2026 18:15:17 +0000, MitchAlsup wrote:
quadi <[email protected]d> posted:
I was not happy that when I did not use a block prefix, I had to omit
the Load Medium and Store Medium instructions from the basic load/store >>>> instructions.
Is LD Medium obtaining a sooth sayer from memory?
Is ST Medium putting a sooth sayer back in memory?
How do you know a sooth sayer fits in 2^(3+n) bytes???
No, I am not referring to one who channels the spirits of the dead.
Instead, the Medium data type refers to 48-bit floating-point values;
although not part of the IEEE 754 standard, they follow the pattern of
the
types defined in it. They offer a precision just above 11 decimal digits,
and an exponent range that exceeds 10 to plus or minus 99, thus
approximating the numbers pocket calculators make available.
Ironically, I had considered an intermediate format a few times, mostly represented as the Binary64 format with the low-order bits cut off.
Mostly hadn't amounted to much.
I did end up experimenting with support for a very niche converter:
(31:0) => (63:0)
As:
(31:4), (11:4), (11:4), (11:4), (11:4), (3:0)
Currently only available in an Imm32 instruction.
Seemingly, this pattern can deal with roughly 2/3 of the FPU constants
that miss as Binary16:
Multiples of 1/3, 1/5 and similar hit with this.
It fails for patterns like 1/7, 1/9, ... or similar, which have a
different bit pattern length (pattern doesn't repeat along an 8-bit spacing).
Patterns like 1/7, 1/9, ... could be instead addressed with a pattern
that repeats on a multiple of 12 bits. But, this sort of thing is
getting a bit niche (would need different patterns to deal with
different fractions).
But, is a relatively affordable way to deal with this pattern; even if
it can't be crammed into a small size in the same way as simple BFP
patterns (and encoding an index into a table of possible patterns wont
save much over expressing the pattern directly).
Also, the 12-bit pattern case can be noted to miss more with patterns
that would hit with 8-bit or with binary16 (the 8-bit pattern case
mostly overlaps as well with the area covered by Binary16). A 6-bit
pattern could still overlap with Binary16's range, but would be more
limited in the fractions it can deal with.
Only really relevant for constant values though (as a live FP format,
would be worse than normal BFP).
Though, can make use of the extra bit left over from the Imm32f
encodings (which are actually stored as Imm33). More a debate though of
if it is worth the non-zero additional LUT cost to do so.
But, this combination would leave, statistically:
Imm16f: 63%
Imm6f 25% (S.E3.M2)
Imm32fu: 71% (8% over 63%, simply Binary64 truncated to 32 bits)
Imm32fn: 88% (25% hit rate over 63%, 8-bit pattern from above)
...
While Imm32fn has a higher hit rate than Imm32fu, they have a non-
overlap, so the combined Imm32fun in this case seems to have around a
96% hit-rate, with around 4% in the "miss" category (irrational
constants, and stuff like 1/7 which has a 3 bit repeating pattern, vs 2-
bit for 1/3 and 1/5).
If I added the 12-bit pattern (in addition to the existing two), could
maybe push it up to around a 97% or 98% hit rate, but the 12-bit pattern
by itself has a lower hit-rate than simply truncating the Binary64 value
to 32 bits, or even Binary16. So, selecting between 8b+12b pattern would
do worse than trunc32 + 8b pattern.
But, dunno.
However, the relative usage of floating point immediate values is low
enough that this doesn't make a big impact on code density.
Not much more "low hanging fruit" for improving code density ATM, but it seems like if I could squeeze out a few more percent on overall code density, it could put XG3 more solidly in the lead vs RV64GC+JX (where, right now it is pretty close and which one wins/loses depends a lot on
the program being tested).
...
quadi <[email protected]d> posted:
I was not happy that when I did not use a block prefix, I had to omit the >> Load Medium and Store Medium instructions from the basic load/store
instructions.
Is LD Medium obtaining a sooth sayer from memory?
Is ST Medium putting a sooth sayer back in memory?
Obviously, this refers to steaks.
On Fri, 24 Apr 2026 05:29:12 +0000, Thomas Koenig wrote:
Obviously, this refers to steaks.
In a higher-level language, one has:
Real
Intermediate
Double Precision
Extended
But in Assembler, one needs
Floating
Medium
Double
Extended
because R for Real can be confused with R for Register, and I for Intermediate can be confused with I for Integer.
John Savard
On Fri, 24 Apr 2026 05:29:12 +0000, Thomas Koenig wrote:
Obviously, this refers to steaks.
In a higher-level language, one has:
Real
Intermediate
Double Precision
Extended
But in Assembler, one needs
Floating
Medium
Double
Extended
because R for Real can be confused with R for Register, and I for Intermediate can be confused with I for Integer.
John Savard
What about triple and quad precision? Or extended triple precision?
This may be a step too far, so I've saved everything if I need to go
back.
On 4/24/2026 7:01 AM, quadi wrote:--------------------
I went with:
H: Half
F/S: Float or Single
D: Double
X: 128-bit (beyond this depends on context)
RV used Q for Binary128, but Q was more widely used for Int64 in my naming.
Int naming:
B/SB/UB: Byte
W/SW/UW: Int16 ("word")
L/SL/UL: Int32 ("long")
T/ST/UT: Int48 ("tword" / triple word), short lived
Q: Int64 ("qword")
RV had used:
B/H/{W|S}/D/Q
John Savard
Obviously, this refers to steaks.I was not happy that when I did not use a block prefix, I had to omit the >>> Load Medium and Store Medium instructions from the basic load/storeIs LD Medium obtaining a sooth sayer from memory?
instructions.
Is ST Medium putting a sooth sayer back in memory?
Obviously, this refers to steaks.I was not happy that when I did not use a block prefix, I had to omit the >>>> Load Medium and Store Medium instructions from the basic load/storeIs LD Medium obtaining a sooth sayer from memory?
instructions.
Is ST Medium putting a sooth sayer back in memory?
But these operations are too rare to include in usual ISAs,
Stefan Monnier <[email protected]> schrieb:
Obviously, this refers to steaks.I was not happy that when I did not use a block prefix, I had to omit theIs LD Medium obtaining a sooth sayer from memory?
Load Medium and Store Medium instructions from the basic load/store >>>> instructions.
Is ST Medium putting a sooth sayer back in memory?
But these operations are too rare to include in usual ISAs,
Well done!
So what to do? What I've been doing all along in this design process -
move the compromise somewhere else, and see if I can put up with it. So
now I've decided to take the 32-bit header for variable-length
instructions, and put the compromise there.
This direction of thinking suggests... that I use some of the opcode
space I still do have free... for special 64-bit instructions that are available without a header. This has been done before in previous
Concertina II iterations. Emergency long instructions - inefficient
because _both_ 32- bit words of the instruction have to begin with 9 or
so overhead bits to indicate they belong to such an instruction... but
less inefficient than adding a whole 32-bit header to the block if you
just need one of them in the block.
That way, I can add lots of extra instructions to be part of the basic headerless instruction set.
BGB <[email protected]> posted:
On 4/24/2026 7:01 AM, quadi wrote:--------------------
I went with:
H: Half
F/S: Float or Single
D: Double
X: 128-bit (beyond this depends on context)
RV used Q for Binary128, but Q was more widely used for Int64 in my naming. >>
Int naming:
B/SB/UB: Byte
W/SW/UW: Int16 ("word")
L/SL/UL: Int32 ("long")
T/ST/UT: Int48 ("tword" / triple word), short lived
Q: Int64 ("qword")
RV had used:
B/H/{W|S}/D/Q
This is what I use. Except I have signed and unsigned integer
arithmetic {B, BS, H, HS, W, WS, D} integers and {H, S, D}
floats.
John Savard
On 4/24/2026 1:52 PM, MitchAlsup wrote:------------------
This is what I use. Except I have signed and unsigned integer
arithmetic {B, BS, H, HS, W, WS, D} integers and {H, S, D}
floats.
It likely depends on which "tradition" one is coming from.
Well, and I guess one could try to argue the merits of, say:
0x1234
$1234
1234H
&H1234
#0x1234
#$1234
16'h1234
...
And, say:
(R10, 16)
16(R10)
[R10+16]
[R10,16]
...
BGB <[email protected]> posted:
On 4/24/2026 1:52 PM, MitchAlsup wrote:------------------
This is what I use. Except I have signed and unsigned integer
arithmetic {B, BS, H, HS, W, WS, D} integers and {H, S, D}
floats.
It likely depends on which "tradition" one is coming from.
IBM 360, 1963.
------------------
Well, and I guess one could try to argue the merits of, say:
0x1234
$1234
1234H
&H1234
#0x1234
#$1234
16'h1234
Use C notation when possible.
...
And, say:
(R10, 16)
16(R10)
[R10+16]
[R10,16]
...
The [] notations tell ASM that the instruction has to be a
memory reference, the () notations do not.
| Sysop: | DaiTengu |
|---|---|
| Location: | Appleton, WI |
| Users: | 1,114 |
| Nodes: | 10 (0 / 10) |
| Uptime: | 492511:54:30 |
| Calls: | 14,267 |
| Calls today: | 3 |
| Files: | 186,320 |
| D/L today: |
26,173 files (8,479M bytes) |
| Messages: | 2,518,387 |