1b78f13911bfe6eda303e91ef215c87a165aae8aeAlexandre Rames// Copyright 2014, VIXL authors 2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved. 3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without 5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met: 6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions of source code must retain the above copyright notice, 8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer. 9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions in binary form must reproduce the above copyright notice, 10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer in the documentation 11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// and/or other materials provided with the distribution. 12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Neither the name of ARM Limited nor the names of its contributors may be 13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// used to endorse or promote products derived from this software without 14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// specific prior written permission. 15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "examples.h" 28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define __ masm-> 30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid GenerateCheckBounds(MacroAssembler* masm) { 32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // uint64_t check_bounds(uint64_t value, uint64_t low, uint64_t high) 33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Argument locations: 34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // value -> x0 35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // low -> x1 36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // high -> x2 37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // First we compare 'value' with the 'low' bound. If x1 <= x0 the N flag will 39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // be cleared. This configuration can be checked with the 'pl' condition. 40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Cmp(x0, x1); 41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Now we will compare 'value' and 'high' (x0 and x2) but only if the 'pl' 43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // condition is verified. If the condition is not verified, we will clear 44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // all the flags except the carry one (C flag). 45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Ccmp(x0, x2, CFlag, pl); 46ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We set x0 to 1 only if the 'ls' condition is satisfied. 48ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 'ls' performs the following test: !(C==1 && Z==0). If the previous 49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // comparison has been skipped we have C==1 and Z==0, so the 'ls' test 50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // will fail and x0 will be set to 0. 51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Otherwise if the previous comparison occurred, x0 will be set to 1 52ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // only if x0 is less than or equal to x2. 53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Cset(x0, ls); 54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Ret(); 56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifndef TEST_EXAMPLES 601e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlvoid run_function(Simulator* simulator, 620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl Instruction* function, 630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl uint64_t value, 640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl uint64_t low, 650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl uint64_t high) { 6688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois simulator->WriteXRegister(0, value); 6788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois simulator->WriteXRegister(1, low); 6888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois simulator->WriteXRegister(2, high); 69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 704a102baf640077d6794c0b33bb976f94b86c532barmvixl simulator->RunFrom(function); 710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl printf("%" PRIu64 " %s between %" PRIu64 " and %" PRIu64 "\n", 720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl value, 7388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois simulator->ReadXRegister(0) ? "is" : "is not", 740f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl low, 750f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl high); 76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 77ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator->ResetState(); 78ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 79ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 80ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint main(void) { 81f2f550c0bfd0f15a4d1c51ff06ec898536f14205Alexandre Rames MacroAssembler masm; 82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Decoder decoder; 83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Simulator simulator(&decoder); 84ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Generate the code for the example function. 86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label check_bounds; 87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&check_bounds); 88ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateCheckBounds(&masm); 89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Run the example function. 920f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl Instruction* function = masm.GetLabelAddress<Instruction*>(&check_bounds); 934a102baf640077d6794c0b33bb976f94b86c532barmvixl run_function(&simulator, function, 546, 50, 1000); 944a102baf640077d6794c0b33bb976f94b86c532barmvixl run_function(&simulator, function, 62, 100, 200); 954a102baf640077d6794c0b33bb976f94b86c532barmvixl run_function(&simulator, function, 200, 100, 200); 96ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0; 98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 99c68cb64496485710cdb5b8480f8fee287058c93farmvixl#else 100c68cb64496485710cdb5b8480f8fee287058c93farmvixl// Without the simulator there is nothing to test. 101c68cb64496485710cdb5b8480f8fee287058c93farmvixlint main(void) { return 0; } 1021e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 103c68cb64496485710cdb5b8480f8fee287058c93farmvixl#endif // TEST_EXAMPLES 104