177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao//===-- switch.S - Implement switch* --------------------------------------===// 277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// 377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// The LLVM Compiler Infrastructure 477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// 577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// This file is distributed under the University of Illinois Open Source 677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// License. See LICENSE.TXT for details. 777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// 877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao//===----------------------------------------------------------------------===// 977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 1077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#include "../assembly.h" 1177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 1277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// 1377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// When compiling switch statements in thumb mode, the compiler 1477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// can use these __switch* helper functions The compiler emits a blx to 1577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// the __switch* function followed by a table of displacements for each 1677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// case statement. On entry, R0 is the index into the table. The __switch* 1777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// function uses the return address in lr to find the start of the table. 1877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// The first entry in the table is the count of the entries in the table. 1977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// It then uses R0 to index into the table and get the displacement of the 2077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// address to jump to. If R0 is greater than the size of the table, it jumps 2177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// to the last entry in the table. Each displacement in the table is actually 2277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// the distance from lr to the label, thus making the tables PIC. 2377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 2477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 2577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao .text 2677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao .syntax unified 2777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 2877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// 2977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// The table contains signed 2-byte sized elements which are 1/2 the distance 3077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// from lr to the target label. 3177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao// 3277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoDEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch16) 3377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao ldrh ip, [lr, #-1] // get first 16-bit word in table 3477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao cmp r0, ip // compare with index 3577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao add r0, lr, r0, lsl #1 // compute address of element in table 3677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao ldrshcc r0, [r0, #1] // load 16-bit element if r0 is in range 3777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao add ip, lr, ip, lsl #1 // compute address of last element in table 3877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao ldrshhs r0, [ip, #1] // load 16-bit element if r0 out of range 3977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao add ip, lr, r0, lsl #1 // compute label = lr + element*2 4077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao bx ip // jump to computed label 4177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 4277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao // tell linker it can break up file at label boundaries 4377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao .subsections_via_symbols 44