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 2-byte sized elements which are 1/2 the distance
30d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar// from lr to the target label.
31d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar//
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines	.p2align 2
33d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel DunbarDEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch16)
34d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	ldrh    ip, [lr, #-1]           // get first 16-bit word in table
35d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	cmp     r0, ip                  // compare with index
36d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	add     r0, lr, r0, lsl #1      // compute address of element in table
37d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	add     ip, lr, ip, lsl #1      // compute address of last element in table
38abd768d337ffc997392323a70c8c53e459173d9bTim Northover	ite lo
39abd768d337ffc997392323a70c8c53e459173d9bTim Northover	ldrshlo r0, [r0, #1]            // load 16-bit element if r0 is in range
40d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	ldrshhs r0, [ip, #1]            // load 16-bit element if r0 out of range
41d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	add     ip, lr, r0, lsl #1      // compute label = lr + element*2
42d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar	bx      ip                      // jump to computed label
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesEND_COMPILERRT_FUNCTION(__switch16)
44d057f7d5eec11c118af2a0620cb06495f03ca8b3Daniel Dunbar
45c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarNO_EXEC_STACK_DIRECTIVE
46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
47