From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from delivery.mailspamprotection.com (delivery.mailspamprotection.com [185.56.84.22]) by sourceware.org (Postfix) with ESMTPS id 9F8153858032 for ; Wed, 19 Jan 2022 04:53:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9F8153858032 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tantosonline.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=tantosonline.com Received: from 107.112.208.35.bc.googleusercontent.com ([35.208.112.107] helo=siteground277.com) by se25.mailspamprotection.com with esmtps (TLSv1.2:AES128-GCM-SHA256:128) (Exim 4.92) (envelope-from ) id 1nA2yf-000GEa-4S for gcc@gcc.gnu.org; Tue, 18 Jan 2022 22:53:46 -0600 Received: from [73.169.135.95] (port=41668 helo=kakukkfu.lan) by siteground277.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.90-.1) (envelope-from ) id 1nA2ye-0000cu-Nj for gcc@gcc.gnu.org; Wed, 19 Jan 2022 04:53:44 +0000 Received: from [192.168.139.176] (router.lan [192.168.139.254]) by kakukkfu.lan (Postfix) with ESMTPSA id 06277AF for ; Tue, 18 Jan 2022 20:53:44 -0800 (PST) To: gcc@gcc.gnu.org From: Andras Tantos Subject: How to generate a call inst. sequence? Message-ID: Date: Tue, 18 Jan 2022 20:53:43 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - siteground277.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tantosonline.com X-Source: X-Source-Args: X-Source-Dir: X-Originating-IP: 35.208.112.107 X-SpamExperts-Domain: siteground277.com X-SpamExperts-Username: 35.208.112.107 Authentication-Results: mailspamprotection.com; auth=pass smtp.auth=35.208.112.107@siteground277.com X-SpamExperts-Outgoing-Class: ham X-SpamExperts-Outgoing-Evidence: Combined (0.12) X-Recommended-Action: accept X-Filter-ID: Pt3MvcO5N4iKaDQ5O6lkdGlMVN6RH8bjRMzItlySaT/eh2jBagdsSxFakAHB0Z0EPUtbdvnXkggZ 3YnVId/Y5jcf0yeVQAvfjHznO7+bT5xBytxzJBgOlCIhBVn7zf5DAxQ+GhOWeJSm0X/4oD2rzYFw cAzbsoHz4zupZn61GBsh55uqY3MhMgFAHq5BxPxPnSWXEV458bUmxaOKcxICtcN9X9K1DzVKciEj mqsTuLPQAKujagVaTNLZ5X+kLHvN+ufcSwqqOlrljbZrM+IOzcdMIqsIyb3aJqs33ZX4HJh0xl54 MAEbe1oNTNeaZ2bNJnWeeuYTXKpbWwq0Jmmi2pLxzMxjTMOIW0hJGap8jYKPi0A2vLwcNEjxGjiC Erd++tkaguJA/XpiTMzAipsso4zIacMilJyGVyjpEgOg2D9z7iXziAEKWBLXmO85pBwPaF+P3CGL wqkaQ0xpotL0Mhypt3L7tZhLu6Os9ceqGjHQelPdLZIWapW8lSgOkuDXqHh92LXjpWxyqA19gVEn 1I8jz3K25BQZYLiRBulvflK9x7G+8oFGjk5+Tb1j8PJET4ztkOffVWdpRr+g5kzHCGrLhMVo7s5r C/i1xA6nwvG8Ksk+aedMfNWSnJswrtlNQ8clfdequDnRZkTy+cnx+wzevvA7ArqeQFEd2navgAmn OvL8Z8nObfEzCxRgiDMmm7RVhDC6rGajPOQMsilQygZImPb9UZXs+o5qEZeRpTi3BT/xcase7lCw 0EQdzS0Qs10w7kA+lqPr+8hLk2VakSAIQcNmgbrA9Q3Mc0d/en13J4Fna6SfOrDTyN/5lNIQ4G/y b0lqja52Mvsrgj8rEk7tj7p+dyFIQ47gnxHR/cQeFcyQ7VJExC7Q4eRzWD0n0z6bhalFEM/pjPCQ A+BAlkOpG56vNwNAHsDD96cr7LsGGzgmrxJJssXyURBEIIDYJMPEAAC5mJVNKOXqIK/gaOh0KZ0w aNrpOKumfDCCvI6IjTPO61He0EDV9KABjOv0PAlbDjazCbhs7qBpykynMvte84F69yef3rjIE9aq rvwwVFFEq45gMHpOzZY5w3lZONZwysYcuEaP1yUDhIrf6APNx91A6n31AAHEln911CjeNHk15Vol AGHS5rCXQKDywZSW8C3uaBiKZzYl7/DyqzzEOtOWX+ZTSN4+SxiH2XbbksYLroyN1JYjH3L7qaaK PM3kr7e7CDjX3ZthNfMWi+djXZBNOJeqVzGgrKtR6HA= X-Report-Abuse-To: spam@quarantine1.mailspamprotection.com X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00, BODY_8BITS, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, WEIRD_PORT autolearn=no autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Jan 2022 04:53:49 -0000 All, I'm working on porting GCC to a processor architecture that doesn't have a (HW) stack nor a call instruction. This means that for calls, I need to generate the following instruction sequence:     // move stack-pointer:     $sp <- $sp-4     // load return address:     $r3 <- return_label     // store return address on stack:     mem[$sp] <- $r3     // jump to callee:     $pc <-   return_label: Now, I can do all of that as a multi-instruction string sequence in my .md file (which is what I'm doing right now), but there are two problems with that approach. First, it hard-codes the temp register ($r3 above) and requires me to reserve it even though it could be used between calls by the register allocator. Second this approach (I think at least) prevents any passes from merging stack-frame preparation for the call arguments, such as eliminating the stack-pointer update above. I thought I could circumvent these problems by emitting a piece of RTL in the 'call' pattern:   (define_expand "call"     [(call       (match_operand:QI 0 "memory_operand" "")       (match_operand 1 "" "")     )]     ""   {     brew_expand_call(Pmode, operands);   }) where brew_expand_call is:   void brew_expand_call(machine_mode mode, rtx *operands)   {     gcc_assert (MEM_P(operands[0]));     rtx_code_label *label = gen_label_rtx();     rtx label_ref = gen_rtx_LABEL_REF(SImode, label);     rtx temp_reg = gen_reg_rtx(mode);     // $sp <- $sp - 4     emit_insn(gen_subsi3(       stack_pointer_rtx,       stack_pointer_rtx,       GEN_INT(4)     ));     // $r3 <-     emit_insn(gen_move_insn(       temp_reg,       label_ref     ));     // mem[$sp] <- $r3     emit_insn(gen_move_insn(       gen_rtx_MEM(Pmode, stack_pointer_rtx),       temp_reg     ));     emit_jump_insn(gen_jump(operands[0]));     emit_label(label);   } If I try to compile the following test:   void x(void)   {   }   int main(void)   {     x();     return 0;   } I get an assert:   during RTL pass: expand   dump file: call.c.252r.expand   call.c: In function ‘main’:   call.c:9:1: internal compiler error: in as_a, at is-a.h:242       9 | }         | ^   0x6999b7 rtx_insn* as_a(rtx_def*)       ../../brew-gcc/gcc/is-a.h:242   0x6999b7 rtx_sequence::insn(int) const       ../../brew-gcc/gcc/rtl.h:1439   0x6999b7 mark_jump_label_1       ../../brew-gcc/gcc/jump.cc:1077   0xcfc31f mark_jump_label_1       ../../brew-gcc/gcc/jump.cc:1171   0xcfc73d mark_all_labels       ../../brew-gcc/gcc/jump.cc:332   0xcfc73d rebuild_jump_labels_1       ../../brew-gcc/gcc/jump.cc:74   0x9e8e62 execute       ../../brew-gcc/gcc/cfgexpand.cc:6845 The reference dump file:   ;; Function x (x, funcdef_no=0, decl_uid=1383, cgraph_uid=1, symbol_order=0)   ;; Generating RTL for gimple basic block 2   try_optimize_cfg iteration 1   Merging block 3 into block 2...   Merged blocks 2 and 3.   Merged 2 and 3 without moving.   Merging block 4 into block 2...   Merged blocks 2 and 4.   Merged 2 and 4 without moving.   try_optimize_cfg iteration 2   ;;   ;; Full RTL generated for this function:   ;;   (note 1 0 3 NOTE_INSN_DELETED)   (note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)   (note 2 3 0 2 NOTE_INSN_FUNCTION_BEG)   ;; Function main (main, funcdef_no=1, decl_uid=1386, cgraph_uid=2, symbol_order=1)   ;; Generating RTL for gimple basic block 2   ;; Generating RTL for gimple basic block 3   EMERGENCY DUMP:   int main ()   {   (note 3 1 2 4 [bb 4] NOTE_INSN_BASIC_BLOCK)   (note 2 3 4 4 NOTE_INSN_FUNCTION_BEG)   (note 4 2 5 2 [bb 2] NOTE_INSN_BASIC_BLOCK)   (insn 5 4 6 2 (set (reg/f:SI 1 $sp)           (minus:SI (reg/f:SI 1 $sp)               (const_int 4 [0x4]))) "call.c":7:5 -1       (nil))   (insn 6 5 7 2 (set (reg:SI 25)           (label_ref:SI 9)) "call.c":7:5 -1       (insn_list:REG_LABEL_OPERAND 9 (nil)))   (insn 7 6 8 2 (set (mem:SI (reg/f:SI 1 $sp) [0  S4 A32])           (reg:SI 25)) "call.c":7:5 -1       (nil))   (jump_insn 8 7 9 2 (set (pc)           (label_ref (mem:QI (symbol_ref:SI ("x") [flags 0x3] ) [0 x S1 A8]))) "call.c":7:5 -1       (nil))   (code_label 9 8 10 2 3 (nil) [1 uses])   (call_insn 10 9 11 2 (call (mem:QI (symbol_ref:SI ("x") [flags 0x3]  ) [0 x S1 A8])           (const_int 16 [0x10])) "call.c":7:5 -1       (nil)       (nil))   (insn 11 10 12 2 (set (reg:SI 23 [ _3 ])           (const_int 0 [0])) "call.c":8:12 -1       (nil))   (code_label 12 11 13 3 4 (nil) [0 uses])   (note 13 12 14 3 [bb 3] NOTE_INSN_BASIC_BLOCK)   (insn 14 13 15 3 (set (reg:SI 24 [ ])           (reg:SI 23 [ _3 ])) "call.c":9:1 -1       (nil))   (jump_insn 15 14 16 3 (set (pc)           (label_ref 17)) "call.c":9:1 -1       (nil))   (code_label 17 16 20 5 2 (nil) [0 uses])   (note 20 17 18 5 [bb 5] NOTE_INSN_BASIC_BLOCK)   (insn 18 20 19 5 (set (reg/i:SI 4 $r4)           (reg:SI 24 [ ])) "call.c":9:1 -1       (nil))   (insn 19 18 0 5 (use (reg/i:SI 4 $r4)) "call.c":9:1 -1       (nil))   } As a test to narrow the problem down, I removed the 'emit_jump_insn' call above. That generated an assembly (thus proving the theory that the assert has something to do with that), but then the assembly doesn't contain my label, only a reference to it; which of course later on would result in a linker error. So, what am I doing wrong and how can I achieve what I want? Thank you all wise sages! Andras