Not sure what "heavyweight" features are being used. I mean, clearly the 6502 is not compiler friendly, but it seems to me the primary reason for that is that the stack isn't as flexible as it is on other CPUs, and much of the overhead of conventional languages is done via parameter passing. But, frankly, I think that's the only serious limitation, a limitation addressed in the '816.
You could use any page in RAM along with X as an SP for a stack, but you're limited to 256 bytes (which is a lot if all you pass around is pointers, but not so much if you're passing around anything else -- C/C++ is pass by value).
Fig-Forth's stack is done via ZP, but if you're willing to eat the cycle costs you can place the stack on any page you want (LDA $200,X works just as well at LDA $0,X, just a touch more expensive.) Most high level stack frames are addressed absolutely.
X is the stack pointer, and decremented for a "push".
So (from Fig-Forth) 16 bit AND:
Code: Select all
LDA 0,X
AND 2,X
LDA 1,X
AND 3,X
INX
INX
That works just fine on another page:
Code: Select all
LDA $200,X
AND $202,X
LDA $201,X
AND $203,X
INX ; drop second argument off stack
INX
If you had this code:
Code: Select all
int b;
void func(int16 a) {
a=a+10;
b = a;
}
Code: Select all
FUNC: CLC ;; Add Top of stack to constant
LDA $200,X
ADC #<10
STA $200,X
LDA $201,X
ADC #>10
STA $201,X
LDA $200,X
STA B
LDA $201,X
STA B+1
INX ;; leaving routine, drop parameter from stack
INX
RTS
Obviously compilers (especially modern compilers) like 16+ bit numbers, but that's a different problem. The compilers really don't care, and it's not a criteria of the language itself per se. With careful coding, you can keep C++ in the 8 Bit realm, you'll just be fighting the compiler a bit as it wants to promote to a larger word size. There's no reason you can't have a compliant C++ compiler that assumes smaller words sizes.
Dumping large stack frames on the 6502 is memory and time expensive. At some point several INX to dump the frame is more expensive than moving X to the accumulator and adding, and moving it back. It's up to the compiler to decide when that is (are you cycle conscious or code size conscious).
But that seems to be the only "heavyweight" operations that the '02 would need to be much more friendly to compilers and, like I said, the '816 fixed that problem. If you do a lot of 16b math, your 6502 code is going to bloat up, or call a lot of subroutines (C65 calls a lot of subroutines). But, '816 solves that issue to with 16b operations. '816 biggest problem is the 16 bit code size, but that's a linker issue.