diff options
author | Björn Gustavsson <[email protected]> | 2017-10-09 11:31:48 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2017-10-09 11:31:48 +0200 |
commit | e38c688d3961bedcd85f842fd052836cb345a902 (patch) | |
tree | 05b1bbdbb0e17ab368e9ec016e24e46c02e4d6d4 /erts/emulator/beam/beam_load.c | |
parent | 52449634868e38087d0c93a0145fcfd9d2de394b (diff) | |
parent | c2e746117b24235b8f2c508ef8f90e35ad422bf2 (diff) | |
download | otp-e38c688d3961bedcd85f842fd052836cb345a902.tar.gz otp-e38c688d3961bedcd85f842fd052836cb345a902.tar.bz2 otp-e38c688d3961bedcd85f842fd052836cb345a902.zip |
Merge branch 'bjorn/erts/pack-with-opcode/OTP-14325'
OTP-14327
OTP-14340
* bjorn/erts/pack-with-opcode/OTP-14325:
Pack operands for combined instructions into the instruction word
beam_makeops: Use named arguments for the code generation functions
Optimize packing for "optional use" operands
beam_makeops: Print the instruction name for fatal packing errors
Introduce a syntax for marking operands as "optional use"
beam_makeops: Refactor parsing of specific instructions
Optimize instruction prefetch
Pack operands into the instruction word
Use 32-bits pointers to C code
Move LD flags for hipe from Makefile.in to configure.in
beam_disasm: Correct printing of y registers
ops.tab: Slightly optimize badmatch on a Y register
macros.tab: Fix assertion in SET_I_REL()
Diffstat (limited to 'erts/emulator/beam/beam_load.c')
-rw-r--r-- | erts/emulator/beam/beam_load.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 9835b1c096..00dd28b26c 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -2578,23 +2578,31 @@ load_code(LoaderState* stp) sp++; } break; - case 'i': /* Initialize packing accumulator. */ - packed = code[--ci]; +#ifdef ARCH_64 + case '1': /* Tightest shift (always 10 bits) */ + ci--; + ASSERT((code[ci] & ~0x1FF8ull) == 0); /* Fits in 10 bits */ + packed = (packed << BEAM_TIGHTEST_SHIFT); + packed |= code[ci] >> 3; + if (packed_label) { + packed_label->packed++; + } break; - case '0': /* Tight shift */ +#endif + case '2': /* Tight shift (10 or 16 bits) */ packed = (packed << BEAM_TIGHT_SHIFT) | code[--ci]; if (packed_label) { packed_label->packed++; } break; - case '6': /* Shift 16 steps */ + case '3': /* Loose shift (16 bits) */ packed = (packed << BEAM_LOOSE_SHIFT) | code[--ci]; if (packed_label) { packed_label->packed++; } break; #ifdef ARCH_64 - case 'w': /* Shift 32 steps */ + case '4': /* Wide shift (32 bits) */ { Uint w = code[--ci]; @@ -2646,8 +2654,31 @@ load_code(LoaderState* stp) sp++; packed = 0; break; +#if defined(ARCH_64) && defined(CODE_MODEL_SMALL) + case '#': /* -1 */ + case '$': /* -2 */ + case '%': /* -3 */ + case '&': /* -4 */ + case '\'': /* -5 */ + case '(': /* -6 */ + /* Pack accumulator contents into instruction word. */ + { + Sint pos = ci - (*prog - '#' + 1); + /* Are the high 32 bits of the instruction word zero? */ + ASSERT((code[pos] & ~((1ull << BEAM_WIDE_SHIFT)-1)) == 0); + code[pos] |= packed << BEAM_WIDE_SHIFT; + if (packed_label) { + ASSERT(packed_label->packed == 1); + packed_label->pos = pos; + packed_label->packed = 2; + packed_label = 0; + } + packed >>= BEAM_WIDE_SHIFT; + } + break; +#endif default: - ASSERT(0); + erts_exit(ERTS_ERROR_EXIT, "beam_load: invalid packing op: %c\n", *prog); } } ASSERT(sp == stack); /* Incorrect program? */ |