diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-01-17 14:52:05 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-01-17 14:52:05 -0800 |
commit | 074e5f54d468730b3719fac72710322170a20535 (patch) | |
tree | 62c1f335e1ac360c32ad57e54677bb5c9a39b2d2 | |
parent | 76ddb8091266741ae046d1b6fdeef4f782617d5b (diff) |
handle atomic operations appearing in libc++
-rw-r--r-- | src/intertyper.js | 17 | ||||
-rw-r--r-- | src/jsifier.js | 14 | ||||
-rw-r--r-- | tests/runner.py | 46 |
3 files changed, 52 insertions, 25 deletions
diff --git a/src/intertyper.js b/src/intertyper.js index 7bc23653..6b46cdbb 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -366,6 +366,8 @@ function intertyper(data, sidePass, baseLineNums) { return '/dev/null'; if (tokensLength >= 3 && token0Text == 'invoke') return 'Invoke'; + if (tokensLength >= 3 && token0Text == 'atomicrmw' || token0Text == 'cmpxchg') + return 'Atomic'; } else { // Already intertyped if (item.parentSlot) @@ -739,6 +741,21 @@ function intertyper(data, sidePass, baseLineNums) { return result.ret; } }); + substrate.addActor('Atomic', { + processItem: function(item) { + item.intertype = 'atomic'; + if (item.tokens[0].text == 'atomicrmw') { + item.op = item.tokens[1].text; + item.tokens.splice(1, 1); + } else { + assert(item.tokens[0].text == 'cmpxchg') + item.op = 'cmpxchg'; + } + var last = getTokenIndexByText(item.tokens, ';'); + item.params = splitTokenList(item.tokens.slice(1, last)).map(parseLLVMSegment); + this.forwardItem(item, 'Reintegrator'); + } + }); // 'landingpad' - just a stub implementation substrate.addActor('Landingpad', { processItem: function(item) { diff --git a/src/jsifier.js b/src/jsifier.js index db6936f6..69a64d1a 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -944,6 +944,20 @@ function JSify(data, functionsOnly, givenFunctions) { + ' } else { ' + getPhiSetsForLabel(phiSets, item.unwindLabel) + makeBranch(item.unwindLabel, item.currLabelId) + ' }'; return ret; }); + makeFuncLineActor('atomic', function(item) { + var type = item.params[0].type; + var param1 = finalizeLLVMParameter(item.params[0]); + var param2 = finalizeLLVMParameter(item.params[1]); + switch (item.op) { + case 'add': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, 'tempValue+' + param2, type) + ',tempValue)'; + case 'xchg': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, param2, type) + ',tempValue)'; + case 'cmpxchg': { + var param3 = finalizeLLVMParameter(item.params[2]); + return '(tempValue=' + makeGetValue(param1, 0, type) + ',(' + makeGetValue(param1, 0, type) + '==' + param2 + ' && (' + makeSetValue(param1, 0, param3, type) + ')),tempValue)'; + } + default: throw 'unhandled atomic op: ' + item.op; + } + }); makeFuncLineActor('landingpad', function(item) { // Just a stub return '{ f0: ' + makeGetValue('_llvm_eh_exception.buf', '0', 'void*') + diff --git a/tests/runner.py b/tests/runner.py index d0056400..6db5aaf3 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -3820,33 +3820,29 @@ def process(filename): self.do_run(src, expected) CORRECT_SIGNS = 0 - def test_atomic_builtins(self): # XXX TODO + def test_atomic(self): src = ''' - type __sync_fetch_and_add (type *ptr, type value, ...) - type __sync_fetch_and_sub (type *ptr, type value, ...) - type __sync_fetch_and_or (type *ptr, type value, ...) - type __sync_fetch_and_and (type *ptr, type value, ...) - type __sync_fetch_and_xor (type *ptr, type value, ...) - type __sync_fetch_and_nand (type *ptr, type value, ...) - - type __sync_add_and_fetch (type *ptr, type value, ...) - type __sync_sub_and_fetch (type *ptr, type value, ...) - type __sync_or_and_fetch (type *ptr, type value, ...) - type __sync_and_and_fetch (type *ptr, type value, ...) - type __sync_xor_and_fetch (type *ptr, type value, ...) - type __sync_nand_and_fetch (type *ptr, type value, ...) - - bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...) - type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...) - - __sync_synchronize (...) - - type __sync_lock_test_and_set (type *ptr, type value, ...) - - void __sync_lock_release (type *ptr, ...) - ''' + #include <stdio.h> + int main() { + int x = 10; + int y = __sync_add_and_fetch(&x, 5); + printf("*%d,%d*\\n", x, y); + x = 10; + y = __sync_fetch_and_add(&x, 5); + printf("*%d,%d*\\n", x, y); + x = 10; + y = __sync_lock_test_and_set(&x, 6); + printf("*%d,%d*\\n", x, y); + x = 10; + y = __sync_bool_compare_and_swap(&x, 9, 7); + printf("*%d,%d*\\n", x, y); + y = __sync_bool_compare_and_swap(&x, 10, 7); + printf("*%d,%d*\\n", x, y); + return 0; + } + ''' - self.do_run(src, 'hello world\n77.\n', + self.do_run(src, '*15,15*\n*15,10*\n*6,10*\n*10,0*\n*7,1*') # libc++ tests |