1d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//===-- switch.S - Implement switch* --------------------------------------===//
2d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//
3d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//                     The LLVM Compiler Infrastructure
4d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//
59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//
8d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//===----------------------------------------------------------------------===//
9d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
10d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar#include "../assembly.h"
11d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
12d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//
13d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// When compiling switch statements in thumb mode, the compiler
14d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// can use these __switch* helper functions  The compiler emits a blx to
15d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// the __switch* function followed by a table of displacements for each
16d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// case statement.  On entry, R0 is the index into the table. The __switch*
17d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// function uses the return address in lr to find the start of the table.
18d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// The first entry in the table is the count of the entries in the table.
19d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// It then uses R0 to index into the table and get the displacement of the
20d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// address to jump to.  If R0 is greater than the size of the table, it jumps
21d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// to the last entry in the table. Each displacement in the table is actually
22d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// the distance from lr to the label, thus making the tables PIC.
23d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
24d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
25d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	.text
26d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	.syntax unified
27d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
28d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//
29d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// The table contains signed byte sized elements which are 1/2 the distance
30d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// from lr to the target label.
31d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//
32d016b38b065fbe3e22584728c3b8bc55fc8a5f9cNick Kledzik	.align 2
33d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel DunbarDEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch8)
34d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	ldrb    ip, [lr, #-1]           // get first byte in table
35d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	cmp     r0, ip                  // signed compare with index
36d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	ldrsbcc r0, [lr, r0]            // get indexed byte out of table
37d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	ldrsbhs r0, [lr, ip]            // if out of range, use last entry in table
38d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	add     ip, lr, r0, lsl #1      // compute label = lr + element*2
39d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	bx      ip                      // jump to computed label
40d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
41d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	// tell linker it can break up file at label boundaries
42d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	.subsections_via_symbols
43d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
44