• Almost Ready to Repeat the Cycle

    From quadibloc@[email protected] (John Savard) to comp.arch on Sun Oct 18 18:39:03 2026
    From Newsgroup: comp.arch

    I was thinking that this iteration of Concertina II was nearly
    perfect...

    and so I wanted to just add one more thing that would bring it all
    crashing down!
    However, after some thought, I determined that what I wanted to do was genuinely impossible, and so I ended up leaving well enough alone.
    My intent was to come up with a slightly changed version of the
    instruction set in which many instructions were just one bit shorter.
    And associate it with a new header type that used... modified
    addresses.

    What's a modified address?
    Well, if a block contains a 32-bit header, then it has seven 32-bit
    instruction slots left.
    If those instructions are to "think" that they aren't interrupted by
    headers - because the idea is to emulate another architecture on my
    dumb CPU which can't handle variable-length instructions without being
    told where they start - I need to map their internal addresses to
    physical addresses... by multiplying them by 1 1/7.
    But I can't multiply by 1 1/7 without dividing by 7, which takes too
    long!

    So I came up with this scheme:
    Multiply by the binary number 1.00100101, which will produce a cycle
    which repeats for every 256 entries. Since 1/7 in binary is
    0.001001001001... going on forever, 0.00100101 is just a little bit
    more than 1/7, and so the header can always be skipped with just a
    modest amount of additional wasted space.

    So if I couldn't figure out a simple way of trivially modifying my ISA
    to make it closer to isomorphic with the target architecture, I could
    just literally emulate, using actual 360 instructions!
    Those occasional skipped 16-bit spots would mean that self-modifying
    code would break. No instruction can start in a 16-bit spot the
    address of which is skipped, but instructions longer than 16 bits are contiguous, so the skipped 16 bits are shifted to the end of the
    instruction if it happens to just precede a 16 bit slot with a skipped
    address.

    No problem, self-modifying code is really rare. However, lots of 360
    programs just put their variables and constants immediately following
    the program code under the purview of the same base register.
    Suddenly, telling the computer when to modify addresses to skip the
    headers, and when to use plain addresses so data accesses work stops
    being possible!

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Sun Oct 18 18:47:11 2026
    From Newsgroup: comp.arch

    What I wrote may have been hard to understand...

    Multiply by the binary number 1.00100101,

    misses a few steps.

    Take, say, a 32 bit address.

    Multiply by the integer 100100101 in binary.

    The result is up to 41 bits long.

    The addresses that we will be interested in are addresses of
    instructions, which align on 16-bit boundaries, and so are all even.

    So actually it's more complicated...

    Take the address.
    Shift one bit right.
    Multiply by binary 100100101.
    Split the number into what comes before, and the last twelve bits.
    What comes before, shifted five bits left (times 32) is the address of
    the 256-bit program block.
    The last 12 bits are mapped to the fourteen remaining 16-bit slots in
    the block, after the header, by means of a table.
    Because of the multiplication by something just bigger than 1 1/7,
    it's guaranteed that after fourteen of them the most significant part
    will advance to the next block. But sometimes it will advance after
    only thirteen.

    So this is what I was talking about.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Sun Oct 18 22:00:52 2026
    From Newsgroup: comp.arch

    I now realize there's actually a way to fix most of the problems with
    this scheme.
    The table I use to convert the addresses generated by multiplication
    to physical locations can have its entries chosen so that the unused
    space in an instruction block always appears at the end, instead of,
    as I was imagining, at any place within the block to make the spacing
    as equal as possible.
    This would solve all the problems with self-modifying code and
    EQUIVALENCE statements, as it could make use of the same mechanism as
    used for the decode fields in headers.
    That doesn't mean it isn't still to crazy to seriously consider.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Tue Oct 20 17:12:07 2026
    From Newsgroup: comp.arch

    On Sun, 18 Oct 2026 22:00:52 GMT, [email protected] (John Savard)
    wrote:

    That doesn't mean it isn't still
    [too]
    crazy to seriously consider.

    It wasn't too crazy for me after all.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From jgd@[email protected] (John Dallman) to comp.arch on Tue Oct 20 20:22:40 2026
    From Newsgroup: comp.arch

    In article <[email protected]>, [email protected] (John Savard) wrote:

    So if I couldn't figure out a simple way of trivially modifying my
    ISA to make it closer to isomorphic with the target architecture, I
    could just literally emulate, using actual 360 instructions!

    Dynamic binary translation is _much_ easier than all these contortions of
    the ISA.

    John
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Wed Oct 21 15:28:02 2026
    From Newsgroup: comp.arch

    On 10/20/2026 2:21 PM, John Dallman wrote:
    In article <[email protected]>, [email protected] (John Savard) wrote:

    So if I couldn't figure out a simple way of trivially modifying my
    ISA to make it closer to isomorphic with the target architecture, I
    could just literally emulate, using actual 360 instructions!

    Dynamic binary translation is _much_ easier than all these contortions of
    the ISA.


    Yes.

    It is one of those things that sometimes isn't given enough credit.

    At some level of feature cost, it may become preferable to emulate a
    feature, or maybe the whole ISA, rather than invest the cost in native hardware support. Where exactly this line is, depends some on the use-case.

    For a more complex ISA with more complex decoding, it may be preferable
    simply to emulate it.


    John

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From John Levine@[email protected] to comp.arch on Thu Oct 22 04:52:52 2026
    From Newsgroup: comp.arch

    According to BGB <[email protected]>:
    So if I couldn't figure out a simple way of trivially modifying my
    ISA to make it closer to isomorphic with the target architecture, I
    could just literally emulate, using actual 360 instructions!

    At some level of feature cost, it may become preferable to emulate a >feature, or maybe the whole ISA, rather than invest the cost in native >hardware support. Where exactly this line is, depends some on the use-case.

    For a more complex ISA with more complex decoding, it may be preferable >simply to emulate it.

    That sounds a lot like IBM's Millicode they use in their mainframes. The hardware
    implements the simple instructions, complex ones run millicode which uses those instructions plus a few others to access internal registers.
    --
    Regards,
    John Levine, [email protected], Primary Perpetrator of "The Internet for Dummies",
    Please consider the environment before reading this e-mail. https://jl.ly
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Thu Oct 22 16:10:13 2026
    From Newsgroup: comp.arch

    BGB <[email protected]> posted:

    On 10/20/2026 2:21 PM, John Dallman wrote:
    In article <[email protected]>, [email protected] (John Savard) wrote:

    So if I couldn't figure out a simple way of trivially modifying my
    ISA to make it closer to isomorphic with the target architecture, I
    could just literally emulate, using actual 360 instructions!

    Dynamic binary translation is _much_ easier than all these contortions of the ISA.


    Yes.

    It is one of those things that sometimes isn't given enough credit.

    At some level of feature cost, it may become preferable to emulate a feature, or maybe the whole ISA, rather than invest the cost in native hardware support.

    Worked great for Transmeta ...

    Where exactly this line is, depends some on the use-case.

    For a more complex ISA with more complex decoding, it may be preferable simply to emulate it.


    John

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Thu Oct 22 16:47:35 2026
    From Newsgroup: comp.arch

    MitchAlsup <[email protected]d> writes:
    BGB <[email protected]> posted:
    At some level of feature cost, it may become preferable to emulate a
    feature, or maybe the whole ISA, rather than invest the cost in native
    hardware support.

    Worked great for Transmeta ...

    That may have to do with the target that they translated to. Intel
    and HP could not get this architecture style to perform well on
    general-purpose programs even when targeting it directly, so why
    should it perform well with a dynamic binary translator?

    OTOH, it seems to work ok for Apple with Rosetta.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bill Findlay@[email protected] to comp.arch on Thu Oct 22 23:42:31 2026
    From Newsgroup: comp.arch

    On 22/10/2026 05:52, John Levine wrote:
    According to BGB <[email protected]>:
    So if I couldn't figure out a simple way of trivially modifying my
    ISA to make it closer to isomorphic with the target architecture, I
    could just literally emulate, using actual 360 instructions!

    At some level of feature cost, it may become preferable to emulate a
    feature, or maybe the whole ISA, rather than invest the cost in native
    hardware support. Where exactly this line is, depends some on the use-case. >>
    For a more complex ISA with more complex decoding, it may be preferable
    simply to emulate it.

    That sounds a lot like IBM's Millicode they use in their mainframes. The hardware
    implements the simple instructions, complex ones run millicode which uses those
    instructions plus a few others to access internal registers.


    That was known as "extracode" on the Ferranti Orion (~1960)
    and the Ferranti Atlas (~1964).

    It was also the means of establishing order code compatibility
    across a range of m/cs - the 1965 ICT/ICL 1900 Series - having
    a wide span of performance and varied h/w bases.
    The smallest 1900s did * and / in extracode, e.g.

    I/O handling and multithreading were extracode throughout the range.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Thu Oct 22 20:23:26 2026
    From Newsgroup: comp.arch

    On 10/22/2026 11:47 AM, Anton Ertl wrote:
    MitchAlsup <[email protected]d> writes:
    BGB <[email protected]> posted:
    At some level of feature cost, it may become preferable to emulate a
    feature, or maybe the whole ISA, rather than invest the cost in native
    hardware support.

    Worked great for Transmeta ...

    That may have to do with the target that they translated to. Intel
    and HP could not get this architecture style to perform well on general-purpose programs even when targeting it directly, so why
    should it perform well with a dynamic binary translator?


    I am not sure, I think Transmeta was using a fixed wide-issue VLIW as
    their underlying ISA. Hard to make this work well even in the best of
    times...


    OTOH, it seems to work ok for Apple with Rosetta.


    Yes.

    ARM64 works well here.


    There also seems to be some interest in the RISC-V space for dynamic translation of x86 to RISC-V; though emulating x86 on RISC-V is likely
    to lead to a not exactly small number of things that are difficult to
    emulate efficiently (EFLAGS being almost kinda evil in some ways; and
    then on an ISA that is in some ways rather poorly equipped to try to
    fake it).

    For x86 emulation attempts in the past, the best option I had found was basically to have the emulator look forwards in the instruction stream
    and infer cases where any EFLAGS updates would be rendered irrelevant by subsequent instructions and then prune them away.


    Though, any efforts to write an x86 emulation layer on top of my ISA
    have fizzled, mostly as the target is already not very fast, so an x86 emulation layer would effectively be too slow to do anything useful with
    it even if the translation is itself reasonably good.

    Well, and there is relatively little I would want to run that:
    I don't already have source code for;
    That I could redistribute without legal risk.

    Like, for example, I probably could write an effective NES emulator on
    top of TestKern and similar, but then "The Big N" is very protective of
    their IP and prone to basically go after anyone who shares any ROMs and sometimes tries to go after the emulators themselves.

    In theory, wouldn't be as bad in the Genesis/MegaDrive space, but the
    same underlying legal issues remain.

    ...


    The other intermediate (and in some ways harder) option being to blend natively running code with emulating parts of the ISA which don't exist
    or are not directly usable.

    Say, for example, running code in userland and then trying to make it
    look like it is bare HW while trying to limit emulation overhead.

    Or, trying to fake RV-V on top of a simpler SIMD implementation.

    This can create new issues that don't exist in full emulation.




    Otherwise, in other news:
    Now finished playing through Riven, in around 5 hours of total gameplay
    time. Still feels as if I had probably played it before. The only time something really felt particularly new/unexpected was at the final end
    of the game realizing I was being railroaded into needing to go straight
    to the end (to ram a telescope through the window which plays the ending cutscene / ends the game).

    Took around 2 hours for this final stretch, but this is where the game
    makes a sort of phase transition from "go around and click various
    things" to "stop and watch a big chunk of cutscenes".

    Or, seeming progression (sessions):
    1 hr: Wander around, open up 2 of the domes;
    2 hr: Do most of the puzzles and areas, open the various domes, ...
    Stopped here: Realized that all that was left was ending stuff.
    2 hr:
    Do animal puzzle, get trap-book back;
    Do colored marble puzzle;
    Visit and trap villain;
    Go and free the trapped lady;
    Finish the game, noting the game had taken away all other options.
    Went looking for ways back off the temple island,
    all seemingly blocked.

    Ran into some minor issues, mostly random minor things.
    Animal puzzle:
    Initially conflated the fish and 'whark' in my mind;
    The latter being... also a big fish...
    Selected the wrong frog symbol at first;
    Well, it is frog from side-view, not frog from top view.
    But, when freed from the trap, is seen from top view, so...
    And the order spheres are based on sound.
    ...
    Marble puzzle:
    Failed to realize the white thing under the switch was a button;
    Visually had interpreted it as a white indicator light.
    ...




    Also came up with a new entropy coding scheme (that I am calling AdSkew
    for now) that slightly beats out AdRice in some of the use-cases I had previously used AdRice for (both better compression and also slightly
    faster to decode).

    Doesn't "replace" Huffman though, as AdSkew and Huffman exist in
    different use-cases (and STF+AdSkew was intended fairly specifically to address some weak points of STF+AdRice; both typically applied to small
    buffer use-case cases).

    Whereas, Huffman is a better fit for medium-to-large buffers (well, say,
    one needing at least a few kB mostly to offset the constant-sized cost
    of the tables and the setup cost of the table initialization).


    Could do a longer description, but the core idea (of AdSkew) is probably obvious enough from an encoding table:

    Skew=0: (All symbols 8-bit)
    xxxxxxx0 00..7F (8, FrSkew++)
    xxxxxxx1 80..FF (8, FrSkew--)
    Skew=1:
    xxxxxx0 00..3F (7, FrSkew++)
    xxxxxx01 40..7F (8, FrSkew--)
    xxxxxxx11 80..FF (9, FrSkew--)
    Skew=2:
    xxxxx0 00..1F ( 6, FrSkew++)
    xxxxx01 20..3F ( 7, FrSkew--)
    xxxxxx011 40..7F ( 9, FrSkew--)
    xxxxxxx111 80..FF (10, FrSkew--)
    Skew=3:
    xxxx0 00..0F ( 5, FrSkew++)
    xxxx01 10..1F ( 6, FrSkew--)
    xxxxx011 20..3F ( 8, FrSkew--)
    xxxxxx0111 40..7F (10, FrSkew--)
    xxxxxxx1111 80..FF (11, FrSkew--)
    Skew=4:
    xxx0 00..07 ( 4, FrSkew++)
    xxx01 08..0F ( 5, FrSkew--)
    xxxx011 10..1F ( 7, FrSkew--)
    xxxxx0111 20..3F ( 9, FrSkew--)
    xxxxxx01111 40..7F (11, FrSkew--)
    xxxxxxx11111 80..FF (12, FrSkew--)

    As noted, used in combination with an STF (Swap Towards Front) symbol reordering transform (with the STF table starting with all of the
    symbols in their normal ordering).

    The Skew parameter is mostly an adaptive value for how steep the table
    is based on previously encoded symbol indices.

    Experimentally, ended up with a 1/8 fractional step, as this seemed to
    give the best results in this case.


    Partly, with both this and the STF, it is a thing of basically balancing adaptation rate with stability:
    Adaptation rate too slow, fails to give usable compression within a
    reasonable number of symbols;
    Adaptation rate too fast, results are noisy and the noise reduces effectiveness.


    For now I was using it in my RP2 STF post-compressor as an alternative
    to AdRice, but could also be applicable to my UPIC image format (which
    uses a very similar entropy coding stage).

    ...


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stefan Monnier@[email protected] to comp.arch on Thu Oct 22 15:45:40 2026
    From Newsgroup: comp.arch

    Anton Ertl [2026-10-22 16:47:35] wrote:
    MitchAlsup <[email protected]d> writes:
    BGB <[email protected]> posted:
    At some level of feature cost, it may become preferable to emulate a
    feature, or maybe the whole ISA, rather than invest the cost in native
    hardware support.
    Worked great for Transmeta ...
    That may have to do with the target that they translated to. Intel
    and HP could not get this architecture style to perform well on general-purpose programs even when targeting it directly, so why
    should it perform well with a dynamic binary translator?
    OTOH, it seems to work ok for Apple with Rosetta.

    I can see 2 important differences:

    - Does the ISA you're emulating have an actively developed hardware
    implementation against which you're going to have to compete?
    - Do you expect to spend 99% of your time emulating a foreign ISA, or do
    you expect to mostly run binaries using your native ISA and just
    occasionally emulate another?


    === Stefan
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Fri Oct 23 07:55:56 2026
    From Newsgroup: comp.arch

    BGB <[email protected]> writes:
    On 10/22/2026 11:47 AM, Anton Ertl wrote:
    OTOH, it seems to work ok for Apple with Rosetta.


    Yes.

    ARM64 works well here.

    I think that Apple's *implementations* of ARM A64 (all OoO on the
    Macs) work well.

    There also seems to be some interest in the RISC-V space for dynamic >translation of x86 to RISC-V; though emulating x86 on RISC-V is likely
    to lead to a not exactly small number of things that are difficult to >emulate efficiently (EFLAGS being almost kinda evil in some ways; and
    then on an ISA that is in some ways rather poorly equipped to try to
    fake it).

    The flags are always a problem, and I don't think that ARM A64 has
    significant advantages over RISC-V here. Yes it has flags of its own,
    but the instructions do not set them the same way as AMD64. AMD64 has instructions that sometimes set the flags and sometimes don't, it has instructions that set C and/or V separately from NZP. And AFAIK ARM
    A64 has subtract with carry (and corresponding carry handling on
    compares), while AMD64 has subtract with borrow; so the meaning of the
    carry is inverted between the two after a subtract or compare
    instruction, while it agrees after an add instruction.

    So the binary translator essentially has to prepare for the worst case
    and generate all the AMD64 flags in case they are then used in a way
    that the binary translator does not see (e.g., after an indirect
    branch), and if the usage is known, can eliminate most or all of this flag-generation code. Pretty much the same for RISC-V.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Fri Oct 23 08:13:07 2026
    From Newsgroup: comp.arch

    Stefan Monnier <[email protected]> writes:
    Anton Ertl [2026-10-22 16:47:35] wrote:
    That may have to do with the target that they translated to. Intel
    and HP could not get this architecture style to perform well on
    general-purpose programs even when targeting it directly, so why
    should it perform well with a dynamic binary translator?
    OTOH, it seems to work ok for Apple with Rosetta.

    I can see 2 important differences:

    - Does the ISA you're emulating have an actively developed hardware
    implementation against which you're going to have to compete?

    It's the same ISA in both cases. You could argue that Intel-based
    Macs are the only competition for Mac users, but the brand loyalty of
    Mac users would be another important difference.

    Certainly the Windows on ARM efforts have to compete with Windows
    computers running on AMD64 hardware implementations. I read about
    slowdowns from binary translation by a factor of 2.

    - Do you expect to spend 99% of your time emulating a foreign ISA, or do
    you expect to mostly run binaries using your native ISA and just
    occasionally emulate another?

    That's an important one. Microsoft tries to get the ISVs of the most
    popular software to support ARM A64, and hopes that's enough to
    commoditize their complement <https://www.joelonsoftware.com/2002/06/12/strategy-letter-v/>.
    Apparently they do not consider the Intel/AMD competition to be enough
    for a commodity, or maybe the the reason is that on Intel and AMD
    processors Linux commiditizes Windows to some extent; the latter
    suggests that the Linux non-compatibility of Windows-on-ARM hardware
    is intended (IIRC some Linix hardware company tried to get Linux to
    run on the CPUs of the first Windows-on-ARM laptops, but eventually
    gave up).

    Anyway, the jury is still out on whether Windows on ARM works this
    time.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Fri Oct 23 03:50:56 2026
    From Newsgroup: comp.arch

    On 10/23/2026 2:55 AM, Anton Ertl wrote:
    BGB <[email protected]> writes:
    On 10/22/2026 11:47 AM, Anton Ertl wrote:
    OTOH, it seems to work ok for Apple with Rosetta.


    Yes.

    ARM64 works well here.

    I think that Apple's *implementations* of ARM A64 (all OoO on the
    Macs) work well.


    OK.

    So, yeah, maybe not so hot then on the A53 or similar in a cheap smartphone?...

    Have noted that things like DOSBox do seem to be painfully slow, but had mostly just figured it was DOSBox just using a plain interpreter in this
    case or something.


    There also seems to be some interest in the RISC-V space for dynamic
    translation of x86 to RISC-V; though emulating x86 on RISC-V is likely
    to lead to a not exactly small number of things that are difficult to
    emulate efficiently (EFLAGS being almost kinda evil in some ways; and
    then on an ISA that is in some ways rather poorly equipped to try to
    fake it).

    The flags are always a problem, and I don't think that ARM A64 has significant advantages over RISC-V here. Yes it has flags of its own,
    but the instructions do not set them the same way as AMD64. AMD64 has instructions that sometimes set the flags and sometimes don't, it has instructions that set C and/or V separately from NZP. And AFAIK ARM
    A64 has subtract with carry (and corresponding carry handling on
    compares), while AMD64 has subtract with borrow; so the meaning of the
    carry is inverted between the two after a subtract or compare
    instruction, while it agrees after an add instruction.


    The main thing I think would be to have some way to cheaply compute them
    and store them away until needed (or restore them from a snapshot state,
    do the op, and then snapshot them again).

    Potentially, with the snapshots of the non-x86 flags, one could use
    these to synthesize the x86 view of the flags if/when they became architecturally visible in the x86 space (with things like moving bits
    around or inverting some bits, etc, being potentially cheaper than fully faking the flags).


    So the binary translator essentially has to prepare for the worst case
    and generate all the AMD64 flags in case they are then used in a way
    that the binary translator does not see (e.g., after an indirect
    branch), and if the usage is known, can eliminate most or all of this flag-generation code. Pretty much the same for RISC-V.


    OK.

    When I tried before, I had a lookahead to detect if a later instruction
    would fully mask away any flags updates from the current instruction,
    and if so emulate it as a no-flags variant.

    But, this still meant needing to emulate flags for when they were not
    needed. But, in this case, was doing logic to directly mimic the state
    of EFLAGS.

    And, then there were instructions that update parts of a register:
    ADD AX, CX
    XCHG AL, DH
    ...

    That can also be a hassle sometimes.


    But, it has been a long time.
    After I wrote an x86 emulator originally, I realized I didn't have a
    strong use-case. The use-cases I had thought I had was better served by
    "just recompiling stuff" or "compile stuff to nearly anything other than 32-bit x86, and use that instead".


    As can be noted, my newer custom emulators (such as jx2vm) still use a
    very similar structure internally to my original x86 emulator.

    Decode as traces, dispatch via a big hash table, and interpret by a
    sequence of decoded instructions with function pointers, ...

    All this was stuff that was originally used in that interpreter.
    Decoder was a bit different, as ironically I was effectively using a listing-driven disassembler for the first pass of the instruction
    decoding. First it would disassemble the instruction and then use the
    mnemonic and instruction-form and similar to select which function
    pointer to use.


    Had considered trying to use big switch blocks over the bytes to decode
    x86, but this is a more painful way to try to approach x86 decoding vs
    the use of looking something up in a listing (and the encoding rules are reasonably consistent if taken from the POV of an instruction listing;
    just arguably bulkier and less efficient).

    Well, similar for writing an assembler:
    Listing: OK;
    Big switches and byte crafting: More painful.

    Kind of an inversion from the case of RISC-style ISAs.


    - anton

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Fri Oct 23 12:24:40 2026
    From Newsgroup: comp.arch

    On Fri, 23 Oct 2026 08:13:07 GMT
    [email protected] (Anton Ertl) wrote:

    Stefan Monnier <[email protected]> writes:
    Anton Ertl [2026-10-22 16:47:35] wrote:
    That may have to do with the target that they translated to. Intel
    and HP could not get this architecture style to perform well on
    general-purpose programs even when targeting it directly, so why
    should it perform well with a dynamic binary translator?
    OTOH, it seems to work ok for Apple with Rosetta.

    I can see 2 important differences:

    - Does the ISA you're emulating have an actively developed hardware
    implementation against which you're going to have to compete?

    It's the same ISA in both cases. You could argue that Intel-based
    Macs are the only competition for Mac users, but the brand loyalty of
    Mac users would be another important difference.

    Certainly the Windows on ARM efforts have to compete with Windows
    computers running on AMD64 hardware implementations. I read about
    slowdowns from binary translation by a factor of 2.

    - Do you expect to spend 99% of your time emulating a foreign ISA,
    or do
    you expect to mostly run binaries using your native ISA and just
    occasionally emulate another?

    That's an important one. Microsoft tries to get the ISVs of the most
    popular software to support ARM A64, and hopes that's enough to
    commoditize their complement <https://www.joelonsoftware.com/2002/06/12/strategy-letter-v/>.
    Apparently they do not consider the Intel/AMD competition to be enough
    for a commodity, or maybe the the reason is that on Intel and AMD
    processors Linux commiditizes Windows to some extent; the latter
    suggests that the Linux non-compatibility of Windows-on-ARM hardware
    is intended (IIRC some Linix hardware company tried to get Linux to
    run on the CPUs of the first Windows-on-ARM laptops, but eventually
    gave up).


    Was it Arm32 or Arm64?

    Anyway, the jury is still out on whether Windows on ARM works this
    time.

    - anton


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Fri Oct 23 14:53:27 2026
    From Newsgroup: comp.arch

    On Thu, 22 Oct 2026 15:45:40 -0400, Stefan Monnier
    <[email protected]> wrote:

    - Does the ISA you're emulating have an actively developed hardware
    implementation against which you're going to have to compete?

    Yes, in some cases.
    The System/360 ISA, in its z/Architecture form, still exists.
    For that matter, FPGA implementations of 680x0 are in use by Amiga
    enthusiasts.

    - Do you expect to spend 99% of your time emulating a foreign ISA, or do
    you expect to mostly run binaries using your native ISA and just
    occasionally emulate another?

    I refuse to judge. Some purchasers of _some implementations_ of my ISA
    may wish to spend 99% of their time emulating one of the foreign ISAs
    for which I provide support in my ISA... so by putting it _in_ the
    ISA, I offer the implementor the opportunity of emulating it very well
    indeed.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Fri Oct 23 15:08:44 2026
    From Newsgroup: comp.arch

    On Fri, 23 Oct 2026 14:53:27 GMT, [email protected] (John Savard)
    wrote:

    I refuse to judge. Some purchasers of _some implementations_ of my ISA
    may wish to spend 99% of their time emulating one of the foreign ISAs
    for which I provide support in my ISA... so by putting it _in_ the
    ISA, I offer the implementor the opportunity of emulating it very well >indeed.

    Oh, and I should also note that I've extended the emulation
    capabilities. I've included an instruction set field in the headers
    for executing code operating on data with alternate widths.

    So now if one were to branch to data memory, the result is defined:
    start emulating the instruction set, for that memory width, specified
    by the instruction set field!

    This has the potential of making PDP-10 lovers happy.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From jgd@[email protected] (John Dallman) to comp.arch on Fri Oct 23 17:23:40 2026
    From Newsgroup: comp.arch

    In article <[email protected]>, [email protected] (Anton Ertl) wrote:

    MitchAlsup <[email protected]d> writes:
    BGB <[email protected]> posted:
    At some level of feature cost, it may become preferable to
    emulate a feature, or maybe the whole ISA, rather than invest
    the cost in native hardware support.

    Worked great for Transmeta ...

    That may have to do with the target that they translated to. Intel
    and HP could not get this architecture style to perform well on general-purpose programs even when targeting it directly, so why
    should it perform well with a dynamic binary translator?

    Transmeta originally thought their VLIW would enable them to run faster
    than x86 even with the translation overhead. When they found that wasn't
    true, they tried to make it use less power than x86 at the same
    performance and failed at that too.

    I can't say that VLIM can never work with general-purpose branchy code,
    but nobody has made it happen yet AFAIK.

    OTOH, it seems to work ok for Apple with Rosetta.

    Yes, possibly they're translating from a general-purpose architecture to another one the runs faster. They've done this several times, on
    different transitions:

    - 68000 to PowerPC with classic MacOS.
    - PowerPC to Intel, with Rosetta I.
    - Intel to ARM with Rosetta II.

    Each time, they dropped the translator after a few years. They've
    announced they will downgrade Rosetta II significantly at macOS 28, due
    in fall 2027. It will then only run games that are unmaintained, but
    popular enough for Apple to whitelist.

    John
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Fri Oct 23 16:21:00 2026
    From Newsgroup: comp.arch

    BGB <[email protected]> writes:
    On 10/23/2026 2:55 AM, Anton Ertl wrote:
    The flags are always a problem, and I don't think that ARM A64 has
    significant advantages over RISC-V here. Yes it has flags of its own,
    but the instructions do not set them the same way as AMD64. AMD64 has
    instructions that sometimes set the flags and sometimes don't, it has
    instructions that set C and/or V separately from NZP. And AFAIK ARM
    A64 has subtract with carry (and corresponding carry handling on
    compares), while AMD64 has subtract with borrow; so the meaning of the
    carry is inverted between the two after a subtract or compare
    instruction, while it agrees after an add instruction.


    The main thing I think would be to have some way to cheaply compute them
    and store them away until needed (or restore them from a snapshot state,
    do the op, and then snapshot them again).

    Potentially, with the snapshots of the non-x86 flags, one could use
    these to synthesize the x86 view of the flags if/when they became >architecturally visible in the x86 space (with things like moving bits >around or inverting some bits, etc, being potentially cheaper than fully >faking the flags).

    Yes, you will not store the flags in eflags format, but in some
    representation that's easy on the target, except when you need to
    produce them in eflags format.

    For NZP, the destination register of the instruction that writes the
    flag contains all the information, so one can store that (and just as
    cheaply on RISC-V as on ARM A64); one does need to sign-extend the
    target size to the full 64 bits.

    C can be computed relatively cheaply even on RISC-V, taking one
    instruction.

    V takes several on RISC-V and may be cheaper to do on ARM A64 (where
    it probably falls out of the computation in the same way as am AMD64
    in many cases).

    And, then there were instructions that update parts of a register:
    ADD AX, CX
    XCHG AL, DH
    ...

    That can also be a hassle sometimes.

    They cost what they cost, when they occur (which is rarely). And they
    even cost quite a bit on hardware implementations of AMD64.

    By contrast, flags are produced by many instructions, and in most
    cases are overwritten without being read.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Fri Oct 23 16:41:58 2026
    From Newsgroup: comp.arch

    Michael S <[email protected]> writes:
    On Fri, 23 Oct 2026 08:13:07 GMT
    [email protected] (Anton Ertl) wrote:
    Apparently they do not consider the Intel/AMD competition to be enough
    for a commodity, or maybe the the reason is that on Intel and AMD
    processors Linux commiditizes Windows to some extent; the latter
    suggests that the Linux non-compatibility of Windows-on-ARM hardware
    is intended (IIRC some Linix hardware company tried to get Linux to
    run on the CPUs of the first Windows-on-ARM laptops, but eventually
    gave up).


    Was it Arm32 or Arm64?

    It's previous generation of Windows-on-ARM laptops with Qualcomm <bla> X1<blabla> chips. Those can run ARM A64 code; not sure about A32/T32.

    The company that tried to get Linux to work on them is Tuxedo, and
    eventually gave up; see <https://www.theregister.com/on-prem/2025/11/26/tuxedo-slams-lid-on-arm-linux-laptop-after-18-months-of-pain/2565428>

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Fri Oct 23 21:20:06 2026
    From Newsgroup: comp.arch

    [email protected] (John Dallman) writes:
    I can't say that VLIM can never work with general-purpose branchy code,

    For branchy code, I can say that it will perform worse than OoO even
    from 1995, because static (compiler) branch prediction performs worse
    than dynamic (hardware) branch prediction, starting from about 1991.

    Joshua Landau posted a brilliant idea here to let EPIC benefit from
    the higher accuracy of dynamic branch prediction, but it would require
    a huge amount of code duplication to be competetive with OoO on
    current processors (with <<10 BMPKI (branch mispredictions per 1000 instructions being common), and reorder buffer windows >500
    instructions.
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From jgd@[email protected] (John Dallman) to comp.arch on Fri Oct 23 23:52:40 2026
    From Newsgroup: comp.arch

    In article <11bf785$1jldo$[email protected]>, [email protected] (BGB)
    wrote:

    On 10/23/2026 2:55 AM, Anton Ertl wrote:
    I think that Apple's *implementations* of ARM A64 (all OoO on the
    Macs) work well.

    So, yeah, maybe not so hot then on the A53 or similar in a cheap smartphone?...

    An A53 is a dual-issue in-order core from 2012. It doesn't use much power,
    but it's a lot slower than Apple's modern cores.

    John
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From jgd@[email protected] (John Dallman) to comp.arch on Fri Oct 23 23:52:40 2026
    From Newsgroup: comp.arch

    In article <[email protected]>, [email protected] (Anton Ertl) wrote:

    Certainly the Windows on ARM efforts have to compete with Windows
    computers running on AMD64 hardware implementations. I read about
    slowdowns from binary translation by a factor of 2.

    I recently had reason to do a little benchmarking of AMD64 code running
    on ARM Windows 11's translator, as compared with the same source built as native code. I was getting about 72% of native code performance in the emulator.

    That's an important one. Microsoft tries to get the ISVs of the
    most popular software to support ARM A64, and hopes that's enough to commoditize their complement

    They've done something slightly more interesting recently. They've
    invented a new ABI for ARM64, which they call ARM64EC. It uses a calling convention based on their one for AMD64, plus some stack markers. The
    effect of this is that you can have processes that are a mixture of
    ARM64EC and AMD64 code. The binary translator recognises the boundaries
    between DLLs, translates the alien ones and leaves the ARM64EC code alone.


    Microsoft did this because they'd found that some ISVs are quite willing
    to produce ARM64 software, but depend on DLLs from other ISVs who aren't interested. Having the willing ISVs use ARM64EC lets them carry on using
    the third-party AMD64 DLLs.

    The drawback is that ARM64EC code can't be mixed in a process with
    "classic" ARM64 code. It would have been nice if they'd invented ARM64EC
    as part of the ARM Windows port, but that started quite a while ago, and
    the problem only became obvious once ISVs started actually producing ARM Windows applications.

    Windows 11 on ARM will run both ARM64EC code and "classic" ARM64 code. It
    does not run 32-bit code. I suspect they left that out because there
    wasn't much ARM32 Windows software, and dropping the support for it meant
    they could make most of the system DLLs into "fat" binaries to support
    the two different ARM64 ABIs without inflating the OS size too much.

    . . . the latter suggests that the Linux non-compatibility of
    Windows-on-ARM hardware is intended

    Maybe. ARM booting arrangements simply aren't as standardised as for
    PC-derived x86 machines. Until fairly recently, Qualcomm had an agreement
    with Microsoft which meant that ARM Windows was only supported on
    Qualcomm hardware and presumably used a Qualcomm boot system. Since
    Qualcomm were only interested in ARM Windows, they would not be likely to
    put effort into Linux compatibility.

    John
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From antispam@[email protected] (Waldek Hebisch) to comp.arch on Sun Oct 25 00:10:17 2026
    From Newsgroup: comp.arch

    Anton Ertl <[email protected]> wrote:
    BGB <[email protected]> writes:
    On 10/22/2026 11:47 AM, Anton Ertl wrote:
    OTOH, it seems to work ok for Apple with Rosetta.


    Yes.

    ARM64 works well here.

    I think that Apple's *implementations* of ARM A64 (all OoO on the
    Macs) work well.

    There also seems to be some interest in the RISC-V space for dynamic >>translation of x86 to RISC-V; though emulating x86 on RISC-V is likely
    to lead to a not exactly small number of things that are difficult to >>emulate efficiently (EFLAGS being almost kinda evil in some ways; and
    then on an ISA that is in some ways rather poorly equipped to try to
    fake it).

    The flags are always a problem, and I don't think that ARM A64 has significant advantages over RISC-V here. Yes it has flags of its own,
    but the instructions do not set them the same way as AMD64. AMD64 has instructions that sometimes set the flags and sometimes don't, it has instructions that set C and/or V separately from NZP. And AFAIK ARM
    A64 has subtract with carry (and corresponding carry handling on
    compares), while AMD64 has subtract with borrow; so the meaning of the
    carry is inverted between the two after a subtract or compare
    instruction, while it agrees after an add instruction.

    So the binary translator essentially has to prepare for the worst case
    and generate all the AMD64 flags in case they are then used in a way
    that the binary translator does not see (e.g., after an indirect
    branch), and if the usage is known, can eliminate most or all of this flag-generation code. Pretty much the same for RISC-V.

    IIUC Apple uses extra instructions for emulation purpose. If
    extra instructions are allowed then flags are modest annoyance:
    one just needs to add a bunch of instructions which instead of
    producing normal result produce flags (in x86 way) in result
    register. Risc-V has tiny advantage here as various extentions
    are encouraged.
    --
    Waldek Hebisch
    --- Synchronet 3.22a-Linux NewsLink 1.2