diff options
Diffstat (limited to 'erts/emulator/beam/jit/x86/generators.tab')
-rw-r--r-- | erts/emulator/beam/jit/x86/generators.tab | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/erts/emulator/beam/jit/x86/generators.tab b/erts/emulator/beam/jit/x86/generators.tab index 8763e34a47..85384ad5bc 100644 --- a/erts/emulator/beam/jit/x86/generators.tab +++ b/erts/emulator/beam/jit/x86/generators.tab @@ -563,3 +563,59 @@ gen.func_end(Func_Label, Entry_Label) { return op; } + +gen.create_bin(Fail, Alloc, Live, Unit, Dst, N, Segments) { + BeamOp* op; + int fixed_args; + int i; + + $NewBeamOp(S, op); + $BeamOpNameArity(op, i_bs_create_bin, 4); + fixed_args = op->arity; + $BeamOpArity(op, (N.val + fixed_args)); + + op->a[0] = Fail; + op->a[1] = Alloc; + op->a[2] = Live; + op->a[3] = Dst; + + for (i = 0; i < N.val; i += 6) { + BeamOpArg Flags; + Uint flags = 0; + + /* Copy all but flags. */ + op->a[i+fixed_args+0] = Segments[i+0]; + op->a[i+fixed_args+1] = Segments[i+1]; + op->a[i+fixed_args+2] = Segments[i+2]; + op->a[i+fixed_args+4] = Segments[i+4]; + op->a[i+fixed_args+5] = Segments[i+5]; + + /* Translate flags. */ + Flags = Segments[i+3]; /* Flags */ + if (Flags.type != TAG_n) { + if (Flags.type == TAG_q) { + Eterm term = beamfile_get_literal(&S->beam, Flags.val); + while (is_list(term)) { + Eterm* consp = list_val(term); + Eterm elem = CAR(consp); + switch (elem) { + case am_little: + flags |= BSF_LITTLE; + break; + case am_native: + flags |= BSF_NATIVE; + break; + } + term = CDR(consp); + } + ASSERT(is_nil(term)); + } + } + Flags.type = TAG_u; + Flags.val = flags; + $NativeEndian(Flags); + op->a[i+fixed_args+3] = Flags; + } + + return op; +} |