sointu/vm/compiler/templates/amd64-386/arithmetic.asm
5684185+vsariola@users.noreply.github.com 8ffe4a70dd feat(vm/compiler): embed templates to executable
2023-07-08 16:39:41 +03: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}}