Liste des Groupes | Revenir à c arch |
On 4/10/2024 12:12 PM, MitchAlsup1 wrote:BGB wrote:
On 4/9/2024 7:28 PM, MitchAlsup1 wrote:BGB-Alt wrote:
>Also the blob of constants needed to be within 512 bytes of the load instruction, which was also kind of an evil mess for branch handling (and extra bad if one needed to spill the constants in the middle of a basic block and then branch over it).In My 66000 case, the constant is the word following the instruction.
Easy to find, easy to access, no register pollution, no DCache pollution.
Yeah.
This was why some of the first things I did when I started extending SH-4 were:My suggestion is that:: "Now that you have screwed around for a while,
Adding mechanisms to build constants inline;
Adding Load/Store ops with a displacement (albeit with encodings borrowed from SH-2A);
Adding 3R and 3RI encodings (originally Imm8 for 3RI).
Did have a mess when I later extended the ISA to 32 GPRs, as (like with BJX2 Baseline+XGPR) only part of the ISA had access to R16..R31.
Usually they were spilled between basic-blocks, with the basic-block needing to branch to the following basic-block in these cases.Also 8-bit branch displacements are kinda lame, ...Why do that to yourself ??
I didn't design SuperH, Hitachi did...But you did not fix them en massé, and you complain about them
But, with BJX1, I had added Disp16 branches.
With BJX2, they were replaced with 20 bit branches. These have the merit of being able to branch anywhere within a Doom or Quake sized binary.
And, if one wanted a 16-bit branch:
MOV.W (PC, 4), R0 //load a 16-bit branch displacement
BRA/F R0
.L0:
NOP // delay slot
.WORD $(Label - .L0)Also kinda bad...Can you say Yech !!
Yeah.Maybe consider now as the appropriate time to strt.
This sort of stuff created strong incentive for ISA redesign...
Granted, it is possible had I instead started with RISC-V instead of SuperH, it is probable BJX2 wouldn't exist.
Though, at the time, the original thinking was that SuperH having smaller instructions meant it would have better code density than RV32I or similar. Turns out not really, as the penalty of the 16 bit ops was needing almost twice as many on average.My 66000 only requires 70% the instruction count of RISC-V,
Things like memcpy/memmove/memset/etc, are function calls in cases when not directly transformed into register load/store sequences.>
My 66000 does not convert them into LD-ST sequences, MM is a single inst-
ruction.
>I have no high-level memory move/copy/set instructions.You have the power to fix it.........
Only loads/stores...
But, at what cost...You would not have to spend hours a week defending the indefensible !!
I had generally avoided anything that will have required microcode or shoving state-machines into the pipeline or similar.Things as simple as IDIV and FDIV require sequencers.
Things like Load/Store-Multiple orIf you like polluted ICaches..............
For small copies, can encode them inline, but past a certain size this becomes too bulky.A copy loop makes more sense for bigger copies, but has a high overhead for small to medium copy.So, there is a size range where doing it inline would be too bulky, but a loop caries an undesirable level of overhead.All the more reason to put it (a highly useful unit of work) into an
instruction.
This is an area where "slides" work well, the main cost is mostly the bulk that the slide adds to the binary (albeit, it is one-off).Consider that the predictor getting into the slide the first time
Which is why it is a 512B memcpy slide vs, say, a 4kB memcpy slide...What if you only wanted to copy 63 bytes ?? Your DW slide fails miserably,
For looping memcpy, it makes sense to copy 64 or 128 bytes per loop iteration or so to try to limit looping overhead.On low end machines, you want to operate at cache port width,
Though, leveraging the memcpy slide for the interior part of the copy could be possible in theory as well.What do you do when the STAT drive wants to write a whole page ??
For LZ memcpy, it is typically smaller, as LZ copies tend to be a lot shorter (a big part of LZ decoder performance mostly being in fine-tuning the logic for the match copies).
Though, this is part of why my runtime library had added a "_memlzcpy(dst, src, len)" and "_memlzcpyf(dst, src, len)" functions, which can consolidate this rather than needing to do it one-off for each LZ decoder (as I see it, it is a similar issue to not wanting code to endlessly re-roll stuff for functions like memcpy or malloc/free, *).
*: Though, nevermind that the standard C interface for malloc is annoyingly minimal, and ends up requiring most non-trivial programs to roll their own memory management.
Ended up doing these with "slides", which end up eating roughly several kB of code space, but was more compact than using larger inline copies.Say (IIRC):Versus::
128 bytes or less: Inline Ld/St sequence
129 bytes to 512B: Slide
Over 512B: Call "memcpy()" or similar.
1-infinity: use MM instruction.
Yeah, but it makes the CPU logic more expensive.By what, 37-gates ??
The slide generally has entry points in multiples of 32 bytes, and operates in reverse order. So, if not a multiple of 32 bytes, the last bytes need to be handled externally prior to branching into the slide.Does this remain sequentially consistent ??
Within a thread, it is fine.What if a SATA drive is reading while you are writing !!
Main wonk is that it does start copying from the high address first.The only things wanting high-low access patterns are dumping stuff to the stack. The fact you CAN get away with it most of the time is no excuse.
Presumably interrupts or similar wont be messing with application memory mid memcpy.
The looping memcpy's generally work from low to high addresses though.As does all string processing.
Les messages affichés proviennent d'usenet.