71 comments

[ 3.2 ms ] story [ 118 ms ] thread
This tutorial seems to perform syscalls directly. That is inadvisable on macos, as the kernel interface is unstable. You should call through libc instead.
Unstable per major macOS version? Don't those break a substantial fraction of working software anyway?
macOS has a lot of work spent on it to ensure backwards compatibility between releases for software.

The situation would have been _far_, _far_ worse otherwise.

Nowhere to the degree as Windows or Linux. MacOS updates are very fragile and almost guaranteed to break software.
Linux on the desktop has far less backwards compatibility than macOS I'd argue. Yes the kernel <-> user space ABI is stable, but anything above that tends to be very messy on Linux.
It depends on what you use on their respective OSes. If you use your MacBook as an expensive Chrome/Slack/Netflix machine, I'd agree it's straight forwards to upgrade macOS. However there is a large range of very expensive professional apps that are pretty much guaranteed not to work on major version updates before the vendor also releases an upgrade, if they ever do. Avid for example. Or Ableton. There's a huge library of 32-bit x86 VST plugins that are now locked away from newer macOS versions due to it dropping 32-bit support.

A lot of hardware didn't get new drivers either, and macOS went and changed that around a few versions back. These are professional products, with many thousands of dollars invested into them, so the upgrade cost is often impossibly high. Hell, I forget the name of the movie, but it was cut on a version of Final Cut Pro (not X) that was five years old when the movie was cut. That editor held onto that their ancient un-upgradeable machine for dear life because that was the workflow they lived and breathed.

For 32-bit, interestingly Apple still maintains a very bare minimum (_not_ covering Mac GUI apps).

This has two customers today:

- on x86 Macs only: older iOS Simulators

- on x86 and arm64 Macs: x86_32 code segments (no syscall emu), for Wine to be able to run 32-bit x86 applications.

I think that the fragile base class problem might be what made Apple get rid of 32-bit x86 app compatibility at the end.

> A lot of hardware didn't get new drivers either, and macOS went and changed that around too

Yeah. KM drivers aren't exactly the most stable thing from release to release ever on macOS. And Apple has been steadily getting rid of those.

The player that actually cares the most about backwards compatibility on the desktop to an insane extent is Microsoft. 32-bit Windows editions (that are able to run 16-bit apps) are only gone in Windows 11. Apple still spends a lot of effort on it but not to the same extent at all.

Windows is better than average but still has considerable holes in backwards compatibility that are particularly visible in games (and ironically, some of the worst are Microsoft's own games under the "Games for Windows" banner e.g. Fable 3), but I've seen a number of other random things break or stop working totally as expected when new versions of Windows come out.
I’m not sure it’s fair to cite breaks due to hardware arch changes as evidence that the OS is bad at backwards compatibility. If anything apple has been better then average for compatibility across hw platforms, offering translation
The breaks I mentioned are just whilst on Intel though. The change to Apple Silicon assuredly broke an ton of stuff but I'm not even counting those.
DAW developers have historically advised users not to upgrade MacOS versions until it is explicitly supported and professionals in the space resist updates at all costs.
This is the only reasonable advice for any OS — DAWs are business-critical and every project is severely time-sensitive and you cannot rely on software vendors at any level of the stack to not break something.
Not in my experience. I've been using the same window manager and the same applications since before my current distro existed.
I bet compiled from source, while what is being discussed here is binary compatibility.
No, I use the distro packages, and have for quite a while now.

Binary compatibility matters less on Linux, true; what people are actually interested in on the desktop is usually UI compatibility, as in keeping the same look and feel and workflow. That's something Linux is a lot better at than either MacOS or MS Windows, both of which force you into new UIs with the shift of fashions and corporate buzzwords.

It is still not what is being discussed here, as binary compatibility across OS versions.
Compatibility through source availability (with the right to adapt) is a good strategy though.

I've used Linux and explicitly chosen open source software since 2004. There's not a single program I'd like to run that does not work today. I've never been bitten by any such compatibility issue.

Binary compatibility is crap though. You are likely to have issues if you try to use a package you found outside of your distribution's repositories for the specific release you use. I guess AppImage and things like this will improve this sad state of affair.

I’ve been using the same window manager on Mac OS X since 2001. It’s not really relevant to this discussion.
They are talking about old applications running on the new operating system. Not upgrading them in lockstep.
This is absolutely not true.
MacOS software is notoriously bad for backward compatibility. Windows is king in this department.
They usually give a very long notice when things are going so it would only be abandonware that breaks.
Agreed. I work on macOS professional apps in the video space and use professional apps in the audio space, and I can only think of 1 plug-in so far that isn’t working correctly on Apple Silicon machines. It looks like there’s an update on the website, but I haven’t had a chance to download it. It’s over 2 years since the first AS machines were released to the public (and probably 2.5 to 3 years since the dev kits were released).

For products I work on, we’ve done OpenGL to Metal, 32-bit to 64-bit, Intel to Apple Silicon. Sure it would be great to never have to change existing code, but it can be done. And most of the audio plug-ins I use are from pretty small vendors who seem to have made the same switches (admittedly, not much OpenGL/Metal use in audio plug-ins).

No, they do not. Where is this trope coming from? Catalina decimating gaming because of the removal of 32-bit support?

Apple doesn’t guarantee syscall compatibility between minor versions, either. You must dynamically link libsystem instead.

libsystem is what you want to use, not libc per se
Depends on priorities. Libc is likely to be better documented and work across oses with less or no hassle.
AFAIK there's no "libc" on macOS. libSystem is "libc".
libc (under the name libsystem_c.dylib) is one of several components that make up libSystem. But none of these dylibs (including libSystem itself) actually exist in the installed image as dylibs: they’re part of the dyld shared cache.
We’re talking about the developer experience, not the implementation. Assuming the IDE doesn’t do it for them, they’re going link against libsystem.
(comment deleted)
This is really neat! My first thought when I read about Perry’s project was that it would be nice to have a macOS translation of the book, so thanks for doing this!
So what's the difference between ARM and Apple Silicon?

It's a little odd seeing it treated as its own unique architecture (for instance with people specifically porting software or writing guides about Apple Silicon rather than ARM in general) when it's just ARM64. Which already has a lot of stuff already ported to it and is quite extensively documented.

Am I missing something? Did Apple do something crazy non-standard when making their chips which make them behave differently?

Apple diverges from standard 64-bit ARM architecture in specific ways: https://developer.apple.com/documentation/xcode/writing-arm6...
I mean, that page only describes ABI differences. I was thinking I would find ARM architecture differences in the silicon. I understand that the ABI is considered part of the specification for 64-bit ARM silicon.
> I mean, that page only describes ABI differences.

It explains how Apple constrains users, and thus the difference between general ARM and Apple Silicon. Which was the question.

> I was thinking I would find ARM architecture differences in the silicon.

Could you explain what you mean exactly? It's an ARM implementation so it has to implement the ISA.

Apple's implementation has a few interesting bits, like a TSO mode (for x86 emulation), and actually has custom ISA extensions (AMX, memory compression, APRR/GXF) which nobody else would be allowed according to Hector Martin.

> nobody else would be allowed according to Hector Martin

I'm not sure of the meaning here. Is it:

a. ISA extensions can't be called by any program not written by Apple? (including Asahi)

b. Nobody else but Apple has the right to have these ISA extensions, but when in Silicon, programmers can use them?

It might be something like this?

c. Nobody else who licenses ARM would be allowed to add extensions to their implementation of the ISA in this way. Apple is more or less a founding member of ARM and has some other deal.

Yes, though that's a different formulation of (2) really:

> Nobody else but Apple has the right to have these ISA extensions

Programmers "can" use Apple extensions because... they're extensions to the ISA, they're not documented but they can't really be blocked off unless they're ring0, and that would make them a lot less useful (the entire point of having extensions for matrix computation is to speed up matrix computations, which are not usually kernel work, and having to syscall to do them would waste the entire thing).

Apple exposes these behind APIs that hide these implementation details. Their own compilers never emit them. Nothing can stop you from embedding them into your binary yourself, of course, but this would be annoying to both you and Apple.
I replied to this post: "Apple diverges from standard 64-bit ARM architecture in specific ways"

I know about Apple Silicon's total store ordering mode and other matrix extensions.

When the poster wrote "Apple diverges from standard 64-bit ARM architecture in specific ways" I expected the link to have more information on the Apple Silicon, but found it was just ABI information.

See for yourself -

https://developer.apple.com/documentation/xcode/writing-arm6...

> I know about Apple Silicon's total store ordering mode and other matrix extensions.

OK?

> When the poster wrote "Apple diverges from standard 64-bit ARM architecture in specific ways" I expected the link to have more information on the Apple Silicon, but found it was just ABI information.

Yees?

That's really no clearer.

The poster wrote that Apple diverges from "standard 64-bit ARM in specific ways", and extensions aside the ABI restrictions is those specific ways: they mean that you can't take random ARM64 assembly or machine code and run it on Apple Silicon without validation that the additional restrictions are respected.

Again, what did you mean exactly? Did you expect Apple Silicon to not implement ARM despite being an implementation of the ARM ISA?

They have features to simplify x86 emulation like additional ALU flags.
I replied to this post: "Apple diverges from standard 64-bit ARM architecture in specific ways"

I know about Apple Silicon's total store ordering mode and other matrix extensions.

When the poster wrote "Apple diverges from standard 64-bit ARM architecture in specific ways" I expected the link to have more information on the Apple Silicon, but found it was just ABI information.

See for yourself -

https://developer.apple.com/documentation/xcode/writing-arm6...

The book assumes running Darwin/OS X, which has consequences specific to that, eg https://github.com/below/HelloSilicon#listing-9-1 but one of the biggest changes is the GPU attached to the arm core, resulting in non-native Apple-specific code. It may not affect the ARM CPU core directly, but if someone is running on Apple Silicon you can assume MPS support whereas you cannot do that for ARM64 targets.

It might also be worth reiterating that this book is, itself, a port from the original, more generic ARM version.

TL;DR it's AAPCS, with a handful of changes that are generally not relevant to most people. The one I would point out is that the frame pointer must always point to something valid; in other words, don't use -fomit-frame-pointer on Apple silicon. (Don't use it elsewhere either, but that's a separate discussion.)
Technically it has to point to _a_ valid frame, but it doesn’t have to be the active function’s frame. So it’s safe to omit setting up a normal call frame, you just aren’t supposed to use it as a GPR.
I.e. don’t do what a former coworker did (on x86) and use both the stack pointer and frame pointer registers as index registers for your FFT implementation.
lmao
When you only have a few GPR names, this sort of thing starts to look tempting. IIRC it was about a 10% perf win, but we didn’t ship it. (We did ship one that used the frame pointer as an index, though.)
> in other words, don't use -fomit-frame-pointer on Apple silicon. (Don't use it elsewhere either, but that's a separate discussion.)

Getting into that separate discussion, I think there's really only one good use case for -fomit-frame-pointer and that's on 32-bit x86, which has only 8 general purpose registers (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI); one of which is the stack pointer (ESP), the other of which is the frame pointer (EBP). Meaning that by default a quarter of the available registers are unavailable to you[1]. With -fomit-frame-pointer, you go from having 6 to 7 free registers. This can have a decent impact on performance; there's a reason you'll see it in old gentoo CFLAGS discussions.

x86_64 added R8-R15 registers (as well as RIP-relative addressing), and implementations do a hell of lot of renaming internally, meaning that the gain from using -fomit-frame-pointer is minimal these days.

[1]: This is in fact even worse when using position independent code, as EBX is used quite often as a hidden GOT argument, leaving you with only 5 useful registers.

Not all ARM chips are made alike, Apple Silicon is yet another variation.
Sure, but the bottom line is can you compile something for ARM64 and have it work on it or not? Since people keep bringing it up I assume the answer is no.

And I suppose that's entirely typical, nothing says Apple as much as as making something as custom and incompatible as possible for literally no reason except ecosystem locking.

The answer is yes.
Then why the ruckus?
Because it’s a superset, and there’s specific characteristics to keep in mind that people have linked multiple times above
The opposite of accessible. Gated behind an expensive purchase.
$900 on sale for m1 laptop. $600 for used. This is less than a day's labor for this crowd.
While I agree in spirit that the relative cost of the Mac isn’t a bad value proposition, I’d definitely mention that wages vary dramatically by locale.

While 100/hr is reasonable for many devs in Silicon Valley, it is fairly high for others.

I'm in central Europe at $80/h ...
Great for you but that doesn’t really change the point. $80/hr is still very high for a lot of the world.
I am tired of seeing this marketing bullshit working so well.

Apple Silicon?

This is ARM ISA and architecture, also known as aarch64.

The repo is all about the Apple-specific bits of doing aarch64 assembly programming for Apple's hardware and OS. Most of the comments already in this thread are about the ways Apple differs from standard aarch64.

You may not like that Apple has created their own brand around their implementation of aarch64, but that's hardly reason to pretend that there is not a meaningful distinction to be made.

The problem I have with that is that this company is known for its disrespect of standards.

Some techies are already confused about the nature of the ISA and architecture.

Pretty soon, people will forget that iOS and macOS are running on ARM, like many many other devices.

For once they have the ability to adopt a standard and even push it forward with the incredible engineering of their hardware teams, but they seems to choose, again, the other route.

You are barking up the wrong tree.

The ABI compatibility is never expected nor is taken for granted, for it is an internal implementation aspect of an operating system. An ISA does not equate to an ABI either. Blaming Apple for devising or augmenting an aarch64 ABI is akin to blaming IBM for using the XCOFF and the AIX ABI on their POWER platforms rather than using the SysV ELF ABI on the same POWER platform that Linux is a signatory to.

Incompatible ABI's used to be a common place across different UNIX flavours from different vendor running on the same ISA. DEC Ultrix running on MIPS used an ABI distinct from that of SGI Irix running on the same MIPS ISA. For many years the ABI was not even recognised as a thing and was rather very loosely based on the original PDP-11 ABI (e.g. the result is either in the zeroeth register of the CPU however it was actully named, or on the stack if the result was too big to fit in, input parameters either in the first 4-5 registers or on the stack etc).

It took years of bickering amongst UNIX vendors until the SysV ELF ABI was finaliased and adopted across all modern UNIX implementations (sans Mach-O on Darwin and XCOFF on AIX). Linux went all in with the ELF ABI as it was well positioned to get away from a zoo of legacy ABI's it historically had to support on different hardware plaftorms (a.out, COFF, ECOFF and whatever else there was out there) even at the cost of the performance loss on the 32-bit x86. Whereas all BSD's (Free, Net and Open) just baulked at it and stuck with the historical BSD ABI for several more years to renege later on.

In this case, many of the divergences exist because the standard AArch64 ABI (AAPCS) wasn't finalized at the time that iOS had to lock its ABI. Several items are actually the standard version from pre-finalization versions of AAPCS, and couldn't be changed to match the standard because iOS binary compatibility was already locked in.
Disrespect of standards? As one of the founding members of Advanced RISC Machines Ltd back in 1990, Apple is rather behind those standards.
The endless digressions about the evil of Apple were tiresome ten years ago. Yes, there is indeed a compelling case to be made that Apple is a force against rather than for software freedom. With that said, last I checked few if any people are compelled to purchase or use an Apple device.

Reasonable people could decide they don’t want to buy Apple products, but then you’re done: you didn’t buy one! :)