Hi Joe.
Sorry for the delay (1 year and 4 months) in responding
to this. There's a long and sad story as to what caused
the delay, but we're here now.
First of all, Hercules is a very important target. Even
if gcc -m31 only allowed writing above 2 GiB on Hercules,
that would still be an extremely important result, and
justify changing the option to -m32, which is what it
inherently is. Just because some arbitrary hardware
masks bits at 24, or 31, or 32, or fails to even do a
wrap at 64, doesn't alter the inherent fact that GCC
is using 32-bit registers. Not 64. Not 31. Not 24.
They are general purpose registers being used, so both
address and data registers are 32 bits.
If you have poorly-written assembler that only works if
addresses are being masked to 24 bits, then there would
be some justification in referring to that as a 24-bit
program.
If you have poorly-written assembler that only works if
addresses are being masked to 31 bits, then there would
be some justification in referring to that as a 31-bit
program.
But if you have a program that works in both of those
AMODEs, ie what IBM calls "AMODE ANY", it would be a
bit odd to call it an ANY-bit program, but that would
be the exact name you need if you want to continue
along that path. And an ANY-including-32-bit program
if it also capable of running as AM32 on any real,
emulated, or theoretical environment.
If you have a poorly-written operating system (like z/OS),
that doesn't provide address masking (via DAT) to 32 bits
for 32-bit programs, so your only option is to run them
as AM31, where negative indexes work, or only run programs
that don't use negative indexes (and ensure that the
high 32 bits of 64 bit registers are 0), then there would
be justification in calling this an AM64-intolerant
program or AM64-tolerant program, respectively.
z/OS has an additional problem that even in AM64, and
even with an AM64-tolerant 32-bit program, there is no
way to request memory in the 2 GiB - 4 GiB region other
than via crapshoot (use_2g_to_32g or whatever), and
even if you win the crapshoot, you can't have a nice
display of the 2 GiB boundary being crossed in a single
instruction. You could if you switched to supervisor
mode/key zero and didn't mind clobbering what was already
there, but you would probably still need to switch DAT off.
And then because you don't know what damage you have
done, you would need to freeze the system and re-IPL.
Instead of attempting that, what I did was use a
properly-written OS, z/PDOS, that uses DAT (virtual
memory) to map the 4 GiB to 8 GiB region to 0 to 4 GiB,
so that even in AM64, you effectively get AM32. This is
the proper way to handle memory when you run 32-bit
programs on a 64-bit system. 32 and 64-bit programs
can run transparently with no mode switching required.
The 4 GiB to 8 GiB virtual storage region is effectively
dead.
It is only used for negative indexes, which are a
fundmanental part of indexed addressing. Even positive
indexes need wrapping. E.g. if you have an address at
the 3.5 GiB mark and you wish to access memory at the
0.5 GiB mark, you would use a positive index of 1 GiB
to get there. On an AM64 system, without a 32-bit mode
in effect, this would index to location 4.5 GiB without
an appropriate DAT mapping.
Note that the index that would do such a thing may be
in a variable (register) that is only known at runtime,
so it is not something that you can change GCC to stop
generating, and I was wrong to ask for that (for years).
So, with that said, I have been able to satisfy your
challenge, using real hardware. A real z114 using a
real 3270 terminal. You can see that beautiful terminal here:
https://groups.io/g/hercules-380/message/2391https://groups.io/g/hercules-380/message/2392
The second photo of the first link shows the CPU (2818)
z114 = 2818-M05/M10
I can obtain a picture of the sticker if needed.
No Hercules in sight.
You could move the goal posts and say that running under
z/VM doesn't count either.
If you do that, I can run z/PDOS directly on an LPAR
and run the memory test (in fact, this has already
been done), but we don't know the procedure (and may
not have permission) to use the HMC to display memory.
z/PDOS can display its own memory, and this can show
that the memory at 8000 is different from location 0,
if you accept z/PDOS reporting itself.
But z/VM is the more "independent" way of displaying
memory, so that there is no chance that z/PDOS can "cheat".
Here is the test code in z/PDOS:
else if (memcmp(prog, "MEMTEST", 7) == 0)
{
printf("writing 4 bytes to address X'7FFE'\n");
memcpy((char *)0x7ffe, "\x01\x02\x03\x04", 4);
printf("done!\n");
*pdos->context->postecb = 0;
pdos->context->regs[15] = 0;
}
and the memcpy generates a single MVC instruction:
MVC 0(4,2),0(3)
Note that MVC is an instruction that has been available
since the S/360 (in the 1960s). I am ac