* It's got split I and D memory.
* All of I/O space is dual-addressed through both memory map and IO ports.
* Because there are insanely simple AVR parts that don't have a stack, the stack pointer is itself a peripheral.
* Half the register file is unusable for 16 bit instructions.
* The half that is usable includes 3 register pairs that have special pointer semantics.
* To accommodate pointer/array semantics in C, those three register pairs have an almost MOD/RM-ian collection of variant loads and stores, each specialized to a particular X, Y, or Z register.
* Because the stack pointer itself is a 16 bit IO peripheral, you have to get interrupt handling implemented properly to adjust it to support the dance AVR-GCC does to set it.
* The instruction encoding itself is a shotgun blast; read an AVR disassembler's mask and lookup table logic, for instance, which is something you don't even need to do in X86.
* For all that trouble, you don't even get a consistent instruction size.
I'd still rather do AVR than X86, but perhaps not by much.