@@ -31,7 +31,7 @@ func (b *builder) supportsRecover() bool {
31
31
// proposal of WebAssembly:
32
32
// https://github.com/WebAssembly/exception-handling
33
33
return false
34
- case "avr" , " riscv64" , "xtensa" :
34
+ case "riscv64" , "xtensa" :
35
35
// TODO: add support for these architectures
36
36
return false
37
37
default :
@@ -116,8 +116,8 @@ func (b *builder) createInvokeCheckpoint() {
116
116
// * The return value (eax, rax, r0, etc) is set to zero in the inline
117
117
// assembly but set to an unspecified non-zero value when jumping using
118
118
// a longjmp.
119
- asmType := llvm .FunctionType (b .uintptrType , []llvm.Type {b .deferFrame .Type ()}, false )
120
119
var asmString , constraints string
120
+ resultType := b .uintptrType
121
121
switch b .archFamily () {
122
122
case "i386" :
123
123
asmString = `
@@ -163,6 +163,21 @@ mov x0, #0
163
163
`
164
164
constraints = "={x0},{x1},~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15},~{x16},~{x17},~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{fp},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{q16},~{q17},~{q18},~{q19},~{q20},~{q21},~{q22},~{q23},~{q24},~{q25},~{q26},~{q27},~{q28},~{q29},~{q30},~{nzcv},~{ffr},~{vg},~{memory}"
165
165
// TODO: SVE registers, which we don't use in TinyGo at the moment.
166
+ case "avr" :
167
+ // Note: the Y register (R28:R29) is a fixed register and therefore
168
+ // needs to be saved manually. TODO: do this only once per function with
169
+ // a defer frame, not for every call.
170
+ resultType = b .ctx .Int8Type ()
171
+ asmString = `
172
+ ldi r24, pm_lo8(1f)
173
+ ldi r25, pm_hi8(1f)
174
+ std z+2, r24
175
+ std z+3, r25
176
+ std z+4, r28
177
+ std z+5, r29
178
+ ldi r24, 0
179
+ 1:`
180
+ constraints = "={r24},z,~{r0},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r25},~{r26},~{r27}"
166
181
case "riscv32" :
167
182
asmString = `
168
183
la a2, 1f
@@ -174,10 +189,11 @@ li a0, 0
174
189
// This case should have been handled by b.supportsRecover().
175
190
b .addError (b .fn .Pos (), "unknown architecture for defer: " + b .archFamily ())
176
191
}
192
+ asmType := llvm .FunctionType (resultType , []llvm.Type {b .deferFrame .Type ()}, false )
177
193
asm := llvm .InlineAsm (asmType , asmString , constraints , false , false , 0 , false )
178
194
result := b .CreateCall (asm , []llvm.Value {b .deferFrame }, "setjmp" )
179
195
result .AddCallSiteAttribute (- 1 , b .ctx .CreateEnumAttribute (llvm .AttributeKindID ("returns_twice" ), 0 ))
180
- isZero := b .CreateICmp (llvm .IntEQ , result , llvm .ConstInt (b . uintptrType , 0 , false ), "setjmp.result" )
196
+ isZero := b .CreateICmp (llvm .IntEQ , result , llvm .ConstInt (resultType , 0 , false ), "setjmp.result" )
181
197
continueBB := b .insertBasicBlock ("" )
182
198
b .CreateCondBr (isZero , continueBB , b .landingpad )
183
199
b .SetInsertPointAtEnd (continueBB )
0 commit comments