sointu/templates/amd64-386/arithmetic.asm
Veikko Sariola e4490faa2e feat(compiler): Add support for targeting WebAssembly.
The working principle is similar as before with x86, but instead of outputting .asm, it outputs .wat. This can be compiled into .wasm by using the wat2wasm assembler.
2020-12-26 23:16:18 +02:00

206 lines
5.7 KiB
NASM

{{- if .HasOp "pop"}}
;-------------------------------------------------------------------------------
; POP opcode: remove (discard) the topmost signal from the stack
;-------------------------------------------------------------------------------
{{- if .Mono "pop" -}}
; Mono: a -> (empty)
{{- end}}
{{- if .Stereo "pop" -}}
; Stereo: a b -> (empty)
{{- end}}
;-------------------------------------------------------------------------------
{{.Func "su_op_pop" "Opcode"}}
{{- if .StereoAndMono "pop"}}
jnc su_op_pop_mono
{{- end}}
{{- if .Stereo "pop"}}
fstp st0
{{- end}}
{{- if .StereoAndMono "pop"}}
su_op_pop_mono:
{{- end}}
fstp st0
ret
{{end}}
{{- if .HasOp "add"}}
;-------------------------------------------------------------------------------
; ADD opcode: add the two top most signals on the stack
;-------------------------------------------------------------------------------
{{- if .Mono "add"}}
; Mono: a b -> a+b b
{{- end}}
{{- if .Stereo "add" -}}
; Stereo: a b c d -> a+c b+d c d
{{- end}}
;-------------------------------------------------------------------------------
{{.Func "su_op_add" "Opcode"}}
{{- if .StereoAndMono "add"}}
jnc su_op_add_mono
{{- end}}
{{- if .Stereo "add"}}
fadd st0, st2
fxch
fadd st0, st3
fxch
ret
{{- end}}
{{- if .StereoAndMono "add"}}
su_op_add_mono:
{{- end}}
{{- if .Mono "add"}}
fadd st1
{{- end}}
{{- if .Mono "add"}}
ret
{{- end}}
{{end}}
{{- if .HasOp "addp"}}
;-------------------------------------------------------------------------------
; ADDP opcode: add the two top most signals on the stack and pop
;-------------------------------------------------------------------------------
; Mono: a b -> a+b
; Stereo: a b c d -> a+c b+d
;-------------------------------------------------------------------------------
{{.Func "su_op_addp" "Opcode"}}
{{- if .StereoAndMono "addp"}}
jnc su_op_addp_mono
{{- end}}
{{- if .Stereo "addp"}}
faddp st2, st0
faddp st2, st0
ret
{{- end}}
{{- if .StereoAndMono "addp"}}
su_op_addp_mono:
{{- end}}
{{- if (.Mono "addp")}}
faddp st1, st0
ret
{{- end}}
{{end}}
{{- if .HasOp "loadnote"}}
;-------------------------------------------------------------------------------
; LOADNOTE opcode: load the current note, scaled to [-1,1]
;-------------------------------------------------------------------------------
{{if (.Mono "loadnote") -}} ; Mono: (empty) -> n, where n is the note{{end}}
{{if (.Stereo "loadnote") -}}; Stereo: (empty) -> n n{{end}}
;-------------------------------------------------------------------------------
{{.Func "su_op_loadnote" "Opcode"}}
{{- if .StereoAndMono "loadnote"}}
jnc su_op_loadnote_mono
{{- end}}
{{- if .Stereo "loadnote"}}
call su_op_loadnote_mono
su_op_loadnote_mono:
{{- end}}
fild dword [{{.INP}}-su_voice.inputs+su_voice.note]
{{.Prepare (.Float 0.0078125)}}
fmul dword [{{.Use (.Float 0.0078125)}}] ; s=n/128.0
{{.Prepare (.Float 0.5)}}
fsub dword [{{.Use (.Float 0.5)}}] ; s-.5
fadd st0, st0 ; 2*s-1
ret
{{end}}
{{- if .HasOp "mul"}}
;-------------------------------------------------------------------------------
; MUL opcode: multiply the two top most signals on the stack
;-------------------------------------------------------------------------------
; Mono: a b -> a*b a
; Stereo: a b c d -> a*c b*d c d
;-------------------------------------------------------------------------------
{{.Func "su_op_mul" "Opcode"}}
jnc su_op_mul_mono
fmul st0, st2
fxch
fadd st0, st3
fxch
ret
su_op_mul_mono:
fmul st1
ret
{{end}}
{{- if .HasOp "mulp"}}
;-------------------------------------------------------------------------------
; MULP opcode: multiply the two top most signals on the stack and pop
;-------------------------------------------------------------------------------
; Mono: a b -> a*b
; Stereo: a b c d -> a*c b*d
;-------------------------------------------------------------------------------
{{.Func "su_op_mulp" "Opcode"}}
{{- if .StereoAndMono "mulp"}}
jnc su_op_mulp_mono
{{- end}}
{{- if .Stereo "mulp"}}
fmulp st2, st0
fmulp st2, st0
ret
{{- end}}
{{- if .StereoAndMono "mulp"}}
su_op_mulp_mono:
{{- end}}
{{- if .Mono "mulp"}}
fmulp st1
ret
{{- end}}
{{end}}
{{- if .HasOp "push"}}
;-------------------------------------------------------------------------------
; PUSH opcode: push the topmost signal on the stack
;-------------------------------------------------------------------------------
; Mono: a -> a a
; Stereo: a b -> a b a b
;-------------------------------------------------------------------------------
{{.Func "su_op_push" "Opcode"}}
{{- if .StereoAndMono "push"}}
jnc su_op_push_mono
{{- end}}
{{- if .Stereo "push"}}
fld st1
fld st1
ret
{{- end}}
{{- if .StereoAndMono "push"}}
su_op_push_mono:
{{- end}}
{{- if .Mono "push"}}
fld st0
ret
{{- end}}
{{end}}
{{- if .HasOp "xch"}}
;-------------------------------------------------------------------------------
; XCH opcode: exchange the signals on the stack
;-------------------------------------------------------------------------------
; Mono: a b -> b a
; stereo: a b c d -> c d a b
;-------------------------------------------------------------------------------
{{.Func "su_op_xch" "Opcode"}}
{{- if .StereoAndMono "xch"}}
jnc su_op_xch_mono
{{- end}}
{{- if .Stereo "xch"}}
fxch st0, st2 ; c b a d
fxch st0, st1 ; b c a d
fxch st0, st3 ; d c a b
{{- end}}
{{- if .StereoAndMono "xch"}}
su_op_xch_mono:
{{- end}}
fxch st0, st1
ret
{{end}}