aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-10-19 16:32:32 +0200
committerBjörn Gustavsson <[email protected]>2011-01-17 15:23:38 +0100
commitc5df89ea0d57e41190155dcf14cbc375dc647bee (patch)
tree309b0ce4d189bd70172b063a6dfc9b8a44f24211
parente31af112f63b11622d6a3a49cb444d5613af2f1f (diff)
downloadotp-c5df89ea0d57e41190155dcf14cbc375dc647bee.tar.gz
otp-c5df89ea0d57e41190155dcf14cbc375dc647bee.tar.bz2
otp-c5df89ea0d57e41190155dcf14cbc375dc647bee.zip
If the wordsize is 64 bits, pack up to 4 operands into a word
In the 32-bit BEAM emulator, it is only possible to pack 3 register operands into one word. Therefore, the move2 instruction (that has 4 operands) needs two words for its operands. Take advantage of the larger wordsize in the 64-bit emulator and pack up to 4 operands into a single word.
-rw-r--r--erts/emulator/beam/beam_load.c2
-rwxr-xr-xerts/emulator/utils/beam_makeops17
2 files changed, 17 insertions, 2 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 73644ecfd6..c190efb0d1 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -1765,7 +1765,7 @@ load_code(LoaderState* stp)
}
stp->specific_op = specific;
- CodeNeed(opc[stp->specific_op].sz+2); /* Extra margin for packing */
+ CodeNeed(opc[stp->specific_op].sz+16); /* Extra margin for packing */
code[ci++] = BeamOpCode(stp->specific_op);
}
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index aa1aba6856..38c2f5bcfe 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -37,12 +37,20 @@ my @pack_mask;
$pack_instr[2] = ['6', 'i'];
$pack_instr[3] = ['0', '0', 'i'];
+$pack_instr[4] = ['6', '6', '6', 'i']; # Only for 64 bit wordsize
$pack_shift[2] = ['0', 'BEAM_LOOSE_SHIFT'];
$pack_shift[3] = ['0', 'BEAM_TIGHT_SHIFT', '(2*BEAM_TIGHT_SHIFT)'];
+$pack_shift[4] = ['0', 'BEAM_LOOSE_SHIFT', # Only for 64 bit wordsize
+ '(2*BEAM_LOOSE_SHIFT)',
+ '(3*BEAM_LOOSE_SHIFT)'];
$pack_mask[2] = ['BEAM_LOOSE_MASK', $WHOLE_WORD];
$pack_mask[3] = ['BEAM_TIGHT_MASK', 'BEAM_TIGHT_MASK', 'BEAM_TIGHT_MASK'];
+$pack_mask[4] = ['BEAM_LOOSE_MASK', # Only for 64 bit wordsize
+ 'BEAM_LOOSE_MASK',
+ 'BEAM_LOOSE_MASK',
+ $WHOLE_WORD];
# There are two types of instructions: generic and specific.
# The generic instructions are those generated by the Beam compiler.
@@ -970,7 +978,14 @@ sub do_pack {
# beginning).
my($up) = ''; # Pack commands (storing back while
# moving forward).
- my($args_per_word) = $packable_args < 4 ? $packable_args : 2;
+ my $args_per_word;
+ if ($packable_args < 4 or $wordsize == 64) {
+ $args_per_word = $packable_args;
+ } else {
+ # 4 packable argument, 32 bit wordsize. Need 2 words.
+ $args_per_word = 2;
+ }
+
my(@shift) = @{$pack_shift[$args_per_word]};
my(@mask) = @{$pack_mask[$args_per_word]};
my(@pack_instr) = @{$pack_instr[$args_per_word]};