diff options
author | Magnus Lång <[email protected]> | 2015-10-23 17:09:16 +0200 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2015-11-27 18:18:38 +0100 |
commit | 148153eb16e873181ff6961f854105a240989265 (patch) | |
tree | 307202287cc27ab559e18675667a9a508a0e4559 /lib/hipe/rtl | |
parent | fd21382290333e6cc25728c1b6dd7c211ddfc297 (diff) | |
download | otp-148153eb16e873181ff6961f854105a240989265.tar.gz otp-148153eb16e873181ff6961f854105a240989265.tar.bz2 otp-148153eb16e873181ff6961f854105a240989265.zip |
hipe: test unit size match in bs_put_binary_all
The unit size field was previously completely discarded when lowering
this instruction from BEAM to Icode.
This feature was previously missing and expressions such as <<0,
<<1:1>>/binary>> would succeed construction when compiled with HiPE.
Diffstat (limited to 'lib/hipe/rtl')
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_binary.erl | 2 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_binary_construct.erl | 22 |
2 files changed, 13 insertions, 11 deletions
diff --git a/lib/hipe/rtl/hipe_rtl_binary.erl b/lib/hipe/rtl/hipe_rtl_binary.erl index b549073050..4525994f7d 100644 --- a/lib/hipe/rtl/hipe_rtl_binary.erl +++ b/lib/hipe/rtl/hipe_rtl_binary.erl @@ -62,7 +62,7 @@ type_of_operation({bs_init,_,_}) -> construct; type_of_operation({bs_init_bits,_}) -> construct; type_of_operation({bs_init_bits,_,_}) -> construct; type_of_operation({bs_put_binary,_,_}) -> construct; -type_of_operation({bs_put_binary_all,_}) -> construct; +type_of_operation({bs_put_binary_all,_,_}) -> construct; type_of_operation({bs_put_float,_,_,_}) -> construct; type_of_operation({bs_put_integer,_,_,_}) -> construct; type_of_operation({bs_put_string,_,_}) -> construct; diff --git a/lib/hipe/rtl/hipe_rtl_binary_construct.erl b/lib/hipe/rtl/hipe_rtl_binary_construct.erl index 97351d0142..1a78320592 100644 --- a/lib/hipe/rtl/hipe_rtl_binary_construct.erl +++ b/lib/hipe/rtl/hipe_rtl_binary_construct.erl @@ -94,10 +94,11 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab var_init_bits(Size, Dst0, Base, Offset, TrueLblName, SystemLimitLblName, FalseLblName); - {bs_put_binary_all, _Flags} -> + {bs_put_binary_all, Unit, _Flags} -> [Src, Base, Offset] = Args, [NewOffset] = get_real(Dst), - put_binary_all(NewOffset, Src, Base, Offset, TrueLblName, FalseLblName); + put_binary_all(NewOffset, Src, Base, Offset, Unit, + TrueLblName, FalseLblName); {bs_put_binary, Size, _Flags} -> case is_illegal_const(Size) of @@ -368,11 +369,9 @@ not_writable_code(Bin, SizeReg, Dst, Base, Offset, Unit, TrueLblName, FalseLblName) -> [SrcBase] = create_unsafe_regs(1), [SrcOffset, SrcSize, TotSize, TotBytes, UsedBytes] = create_regs(5), - [DivLbl,IncLbl,AllLbl] = Lbls = create_lbls(3), - [DivLblName,IncLblName,AllLblName] = get_label_names(Lbls), + [IncLbl,AllLbl] = Lbls = create_lbls(2), + [IncLblName,AllLblName] = get_label_names(Lbls), [get_base_offset_size(Bin, SrcBase, SrcOffset, SrcSize, FalseLblName), - is_divisible(SrcSize, Unit, DivLblName, FalseLblName), - DivLbl, hipe_rtl:mk_alu(TotSize, SrcSize, add, SizeReg), hipe_rtl:mk_alu(TotBytes, TotSize, add, ?LOW_BITS), hipe_rtl:mk_alu(TotBytes, TotBytes, srl, ?BYTE_SHIFT), @@ -383,7 +382,7 @@ not_writable_code(Bin, SizeReg, Dst, Base, Offset, Unit, hipe_rtl:mk_move(UsedBytes, hipe_rtl:mk_imm(256)), AllLbl, allocate_writable(Dst, Base, UsedBytes, TotBytes, TotSize), - put_binary_all(Offset, Bin, Base, hipe_rtl:mk_imm(0), + put_binary_all(Offset, Bin, Base, hipe_rtl:mk_imm(0), Unit, TrueLblName, FalseLblName)]. allocate_writable(Dst, Base, UsedBytes, TotBytes, TotSize) -> @@ -748,13 +747,16 @@ var_init_bits(Size, Dst, Base, Offset, TrueLblName, SystemLimitLblName, FalseLbl hipe_rtl:mk_move(Dst, TmpDst), hipe_rtl:mk_goto(TrueLblName)]. -put_binary_all(NewOffset, Src, Base, Offset, TLName, FLName) -> +put_binary_all(NewOffset, Src, Base, Offset, Unit, TLName, FLName) -> [SrcBase,SrcOffset,NumBits] = create_regs(3), + [ContLbl] = create_lbls(1), CCode = binary_c_code(NewOffset, Src, Base, Offset, NumBits, TLName), AlignedCode = copy_aligned_bytes(SrcBase, SrcOffset, NumBits, Base, Offset, NewOffset, TLName), - get_base_offset_size(Src, SrcBase, SrcOffset, NumBits,FLName) ++ - test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode). + [get_base_offset_size(Src, SrcBase, SrcOffset, NumBits,FLName), + is_divisible(NumBits, Unit, hipe_rtl:label_name(ContLbl), FLName), + ContLbl + |test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode)]. test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode) -> [Tmp] = create_regs(1), |