[Help-bitfield-optimization] bitfield insert instruction
Mahesh Bodapati
maheshbodapati90@gmail.com
Mon Jun 5 11:13:00 GMT 2017
Hi,
Could you please help me in bitfield optimizations…
Source c code :
$ cat main.c
int main()
{
typedef struct {
unsigned int field1: 5;
unsigned int bit1:1;
unsigned int field2:10;
unsigned int field3:16;
} example_register_t;
example_register_t example_register = {(unsigned int)16, 1, 500, 65535};
return 0;
}
Assembly code for arm :
main:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #12
ldrb r3, [fp, #-8]
mov r2, #16
bfi r3, r2, #0, #5
strb r3, [fp, #-8]
ldrb r3, [fp, #-8]
orr r3, r3, #32
strb r3, [fp, #-8]
ldrh r3, [fp, #-8] @ movhi
mov r2, #500
bfi r3, r2, #6, #10
strh r3, [fp, #-8] @ movhi
mvn r3, #0
strh r3, [fp, #-6] @ movhi
mov r3, #0
mov r0, r3
sub sp, fp, #0
@ sp needed
ldr fp, [sp], #4
bx lr
Code changes :
I have added bitfield insert instruction for Microblaze target like below..
(define_expand "insv"
[(set (zero_extract:SI (match_operand 0 "register_operand" "+r")
(match_operand 1 "const_int_M_operand" "S")
(match_operand 2 "const_int_M_operand" "S"))
(match_operand 3 "register_operand" "r"))]
"TARGET_HAS_BITFIELD"
(define_insn "insv_32"
[(set (zero_extract (match_operand 0 "register_operand" "+r")
(match_operand 1 "const_int_M_operand" "S")
(match_operand 2 "const_int_M_operand" "S"))
(match_operand 3 "register_operand" "r"))]
"TARGET_HAS_BITFIELD && UINTVAL (operands[1]) > 0
&& UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
"bsi %0, %3, %1, %2"
(define_constraint "S"
"A constant in the range 0 to 31 (inclusive)."
(and (match_code "const_int")
(match_test "ival > 0 && ival < 0x20")))
but I didn't see the generation of bitfield insert instruction . I
have seen a combination of ori and andi instructions where as in ARM,I
have seen the bitfield insert instruction.
any suggestions?
Assembly code for Microblaze :
main:
.frame r19,12,r15 # vars= 4, regs= 1, args= 0
.mask 0x00080000
addik r1,r1,-12
swi r19,r1,8
addk r19,r1,r0
lwi r3,r19,4
andi r3,r3,134217727 #and2
ori r3,r3,-2147483648
swi r3,r19,4
lwi r3,r19,4
ori r3,r3,67108864
swi r3,r19,4
lwi r3,r19,4
andi r3,r3,-67043329 #and2
ori r3,r3,32768000
swi r3,r19,4
addik r3,r0,-1 # 0xffffffffffffffff
shi r3,r19,6
addk r3,r0,r0
addk r1,r19,r0
lwi r19,r1,8
addik r1,r1,12
rtsd r15,8
nop # Unfilled delay slot
.end main
Analysis:
when I was debugging the GCC source code ,GCC is adding CODE_FOR_insv
but while matching operands,GCC is returning 0.
Stack trace :
#0 insn_operand_matches (icode=CODE_FOR_insv, opno=0, operand=0x7ffff7eae4c8)
at /proj/esdt_sdk/mbodapati/final_builds/mb_source_co/rdi_scripts/../build/lin64/ctng_bld/target_build/src/gcc-custom/gcc/optabs.c:6806
#1 0x0000000000872b62 in maybe_legitimize_operand_same_code
(icode=CODE_FOR_insv, opno=0, op=0x7fffffffd200)
at /proj/esdt_sdk/mbodapati/final_builds/mb_source_co/rdi_scripts/../build/lin64/ctng_bld/target_build/src/gcc-custom/gcc/optabs.c:6836
#2 0x0000000000872d87 in maybe_legitimize_operand
(icode=CODE_FOR_insv, opno=0, nops=4, ops=<value optimized out>)
at /proj/esdt_sdk/mbodapati/final_builds/mb_source_co/rdi_scripts/../build/lin64/ctng_bld/target_build/src/gcc-custom/gcc/optabs.c:6888
#3 maybe_legitimize_operands (icode=CODE_FOR_insv, opno=0, nops=4,
ops=<value optimized out>)
at /proj/esdt_sdk/mbodapati/final_builds/mb_source_co/rdi_scripts/../build/lin64/ctng_bld/target_build/src/gcc-custom/gcc/optabs.c:6973
#4 0x0000000000872fd1 in maybe_gen_insn (icode=CODE_FOR_insv,
nops=<value optimized out>, ops=0x7fffffffd200)
at /proj/esdt_sdk/mbodapati/final_builds/mb_source_co/rdi_scripts/../build/lin64/ctng_bld/target_build/src/gcc-custom/gcc/optabs.c:6992
#5 0x0000000000873359 in maybe_expand_insn (icode=<value optimized
out>, nops=<value optimized out>, ops=<value optimized out>)
at /proj/esdt_sdk/mbodapati/final_builds/mb_source_co/rdi_scripts/../build/lin64/ctng_bld/target_build/src/gcc-custom/gcc/optabs.c:7040
#6 0x00000000006a8ab8 in store_bit_field_using_insv
(insv=0x7fffffffd350, op0=<value optimized out>, bitsize=5, bitnum=27,
value=0x7ffff7dc2670)
at /proj/esdt_sdk/mbodapati/final_builds/mb_source_co/rdi_scripts/../build/lin64/ctng_bld/target_build/src/gcc-custom/gcc/expmed.c:704
#7 0x00000000006ac855 in store_bit_field_1 (str_rtx=<value optimized
out>, bitsize=5, bitnum=0, bitregion_start=0, bitregion_end=31,
fieldmode=VOIDmode, value=0x7ffff7dc2670, reverse=false,
Main.c.213r.expand:
;
(note 1 0 3 NOTE_INSN_DELETED)
(note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(note 2 3 7 2 NOTE_INSN_FUNCTION_BEG)
(insn 7 2 8 2 (set (reg:SI 46)
(mem/j/c:SI (reg/f:SI 37 virtual-stack-vars) [0 +0 S4 A32]))
main.c:10 -1
(nil))
(insn 8 7 9 2 (set (reg:SI 47)
(and:SI (reg:SI 46)
(const_int 134217727 [0x7ffffff]))) main.c:10 -1
(nil))
(insn 9 8 10 2 (set (reg:SI 48)
(ior:SI (reg:SI 47)
(const_int -2147483648 [0xffffffff80000000]))) main.c:10 -1
(nil))
(insn 10 9 13 2 (set (mem/j/c:SI (reg/f:SI 37 virtual-stack-vars) [0 +0 S4 A32])
(reg:SI 48)) main.c:10 -1
(nil))
(insn 13 10 14 2 (set (reg:SI 51)
(mem/j/c:SI (reg/f:SI 37 virtual-stack-vars) [0 +0 S4 A32]))
main.c:10 -1
(nil))
(insn 14 13 15 2 (set (reg:SI 52)
(ior:SI (reg:SI 51)
(const_int 67108864 [0x4000000]))) main.c:10 -1
(nil))
(insn 15 14 18 2 (set (mem/j/c:SI (reg/f:SI 37 virtual-stack-vars) [0
+0 S4 A32])
(reg:SI 52)) main.c:10 -1
(nil))
(insn 18 15 19 2 (set (reg:SI 55)
(mem/j/c:SI (reg/f:SI 37 virtual-stack-vars) [0 +0 S4 A32]))
main.c:10 -1
(nil))
(insn 19 18 20 2 (set (reg:SI 56)
(and:SI (reg:SI 55)
(const_int -67043329 [0xfffffffffc00ffff]))) main.c:10 -1
(nil))
(insn 20 19 21 2 (set (reg:SI 57)
(ior:SI (reg:SI 56)
(const_int 32768000 [0x1f40000]))) main.c:10 -1
(nil))
(insn 21 20 22 2 (set (mem/j/c:SI (reg/f:SI 37 virtual-stack-vars) [0
+0 S4 A32])
(reg:SI 57)) main.c:10 -1
(nil))
(insn 22 21 23 2 (set (reg:HI 58)
(const_int -1 [0xffffffffffffffff])) main.c:10 -1
(nil))
(insn 23 22 24 2 (set (mem/j/c:HI (plus:SI (reg/f:SI 37 virtual-stack-vars)
(const_int 2 [0x2])) [1 example_register.field3+0 S2 A16])
(reg:HI 58)) main.c:10 -1
(nil))
(insn 24 23 27 2 (set (reg:SI 42 [ _6 ])
(const_int 0 [0])) main.c:17 -1
(nil))
(insn 27 24 31 2 (set (reg:SI 43 [ <retval> ])
(reg:SI 42 [ _6 ])) -1
(nil))
(insn 31 27 32 2 (set (reg/i:SI 3 r3)
(reg:SI 43 [ <retval> ])) main.c:18 -1
(nil))
(insn 32 31 0 2 (use (reg/i:SI 3 r3)) main.c:18 -1
(nil))
;
Thanks,
Mahesh
More information about the Gcc-help
mailing list