Home | History | Annotate | Line # | Download | only in arm
      1      1.1  joerg //===-- switch.S - Implement switch* --------------------------------------===//
      2      1.1  joerg //
      3      1.1  joerg //                     The LLVM Compiler Infrastructure
      4      1.1  joerg //
      5      1.1  joerg // This file is dual licensed under the MIT and the University of Illinois Open
      6      1.1  joerg // Source Licenses. See LICENSE.TXT for details.
      7      1.1  joerg //
      8      1.1  joerg //===----------------------------------------------------------------------===//
      9      1.1  joerg 
     10      1.1  joerg #include "../assembly.h"
     11      1.1  joerg 
     12      1.1  joerg //
     13      1.1  joerg // When compiling switch statements in thumb mode, the compiler
     14      1.1  joerg // can use these __switch* helper functions  The compiler emits a blx to
     15      1.1  joerg // the __switch* function followed by a table of displacements for each
     16      1.1  joerg // case statement.  On entry, R0 is the index into the table. The __switch*
     17      1.1  joerg // function uses the return address in lr to find the start of the table.
     18      1.1  joerg // The first entry in the table is the count of the entries in the table.
     19      1.1  joerg // It then uses R0 to index into the table and get the displacement of the
     20      1.1  joerg // address to jump to.  If R0 is greater than the size of the table, it jumps
     21      1.1  joerg // to the last entry in the table. Each displacement in the table is actually
     22      1.1  joerg // the distance from lr to the label, thus making the tables PIC.
     23      1.1  joerg 
     24      1.1  joerg 
     25      1.1  joerg 	.text
     26      1.1  joerg 	.syntax unified
     27      1.1  joerg 
     28      1.1  joerg //
     29      1.1  joerg // The table contains signed 4-byte sized elements which are the distance
     30      1.1  joerg // from lr to the target label.
     31      1.1  joerg //
     32  1.1.1.2  joerg 	.p2align 2
     33      1.1  joerg DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch32)
     34      1.1  joerg 	ldr     ip, [lr, #-1]            // get first 32-bit word in table
     35      1.1  joerg 	cmp     r0, ip                   // compare with index
     36      1.1  joerg 	add     r0, lr, r0, lsl #2       // compute address of element in table
     37      1.1  joerg 	add     ip, lr, ip, lsl #2       // compute address of last element in table
     38      1.1  joerg 	ite lo
     39      1.1  joerg 	ldrlo   r0, [r0, #3]             // load 32-bit element if r0 is in range
     40      1.1  joerg 	ldrhs   r0, [ip, #3]             // load 32-bit element if r0 out of range
     41      1.1  joerg 	add     ip, lr, r0               // compute label = lr + element
     42      1.1  joerg 	bx      ip                       // jump to computed label
     43      1.1  joerg END_COMPILERRT_FUNCTION(__switch32)
     44      1.1  joerg 
     45