// vtest build: !msvc fn test_inline_asm() { a, mut b := 10, 0 asm i386 { mov eax, a mov b, eax ; +r (b) ; r (a) ; eax } assert a == 10 assert b == 10 mut c := 0 asm i386 { mov c, 5 ; +r (c) } assert c == 5 d, e, mut f := 10, 2, 0 asm i386 { mov f, d add f, e add f, 5 ; +r (f) // output ; r (d) r (e) // input } assert d == 10 assert e == 2 assert f == 17 mut j := 0 // do 5*3 // adding three, five times asm i386 { mov ecx, 5 // loop 5 times loop_start: add j, 3 loop loop_start ; +r (j) ; ; ecx } assert j == 5 * 3 // k := 0 // Wait for tcc to implement goto, and gcc has odd errors // mut loops := 0 // outside_label: // if k != 5 { // loops++ // asm goto amd64 { // mov k, 1 // mov k, 5 // jmp outside_label // ; =r (k) as k // ; r (k) // ; // ; outside_label // } // } // assert loops == 1 // assert k == 5 // not marked as mut because we dereference m to change l l := 5 m := &l asm i386 { movb [m], 7 ; ; r (m) } assert l == 7 // same as above n := [5, 9, 0, 4] asm i386 { loop_start2: addw [in_data + ecx * 4 + 0], 2 loop loop_start2 addw [in_data + ecx * 4 + 0], 2 ; ; c (n.len - 1) // c is counter (loop) register r (n.data) as in_data } assert n == [7, 11, 2, 6] mut manu := Manu{} asm i386 { mov eax, 0 cpuid ; =b (manu.ebx) =d (manu.edx) =c (manu.ecx) ; ; eax } assert manu.str()[0].is_capital() } @[packed] struct Manu { mut: ebx u32 edx u32 ecx u32 zero u8 // for string } fn (mut m Manu) str() string { return unsafe { string{ str: &u8(m) len: 12 is_lit: 1 } } } fn test_flag_output() { a, b := 4, 9 mut out := false asm i386 { cmp a, b ; =@ccl (out) ; r (a) r (b) } assert out asm i386 { cmp b, a ; =@ccl (out) ; r (a) r (b) } assert !out zero := 0 asm i386 { cmp zero, zero ; =@ccz (out) ; r (zero) } assert out mut maybe_four := 4 mut four := 4 asm i386 { subl four, maybe_four testl four, maybe_four movl maybe_four, 9 ; +m (maybe_four) +r (four) =@ccz (out) } assert out assert maybe_four == 9 } fn test_asm_generic() { u := u64(49) b := unsafe { bool(0) } assert generic_asm(u) == 14 assert u == 63 assert generic_asm(b) == true assert b == true } fn generic_asm[T](var &T) T { mut ret := unsafe { T(14) } unsafe { asm volatile i386 { add var, ret ; +m (var[0]) as var +r (ret) ; ; memory } } return ret }